Merge PR #885 into 12.0

Signed-off-by yvaucher
This commit is contained in:
OCA-git-bot
2021-01-04 16:51:45 +00:00
12 changed files with 238 additions and 259 deletions

View File

@@ -1,6 +1,2 @@
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
# Copyright 2018 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from . import wizard
from . import models

View File

@@ -1,10 +1,12 @@
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
# Copyright 2018 Camptocamp SA
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
{
"name": "Move Stock Location",
"version": "12.0.1.3.2",
"version": "12.0.2.0.1",
"author": "Julius Network Solutions, "
"BCIM,"
"Camptocamp,"
"Odoo Community Association (OCA)",
"summary": "This module allows to move all stock "
"in a stock location to an other one.",
@@ -17,6 +19,7 @@
"data": [
'data/stock_quant_view.xml',
'views/stock_picking_type_views.xml',
'views/stock_picking.xml',
'wizard/stock_move_location.xml',
],
}

View File

@@ -0,0 +1,44 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_picking_fillwithstock
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-01-22 08:26+0000\n"
"PO-Revision-Date: 2017-01-22 08:26+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: stock_picking_fillwithstock
#: model:ir.ui.view,arch_db:stock_picking_fillwithstock.view_picking_form
msgid "Fill with stock"
msgstr "Remplir avec le stock"
#. module: stock_picking_fillwithstock
#: code:addons/stock_picking_fillwithstock/models/stock.py:35
#, python-format
msgid "Moves lines already exsits"
msgstr "Des lignes existent déjà"
#. module: stock_picking_fillwithstock
#: code:addons/stock_picking_fillwithstock/models/stock.py:60
#, python-format
msgid "Nothing to move"
msgstr "Rien à déplacer"
#. module: stock_picking_fillwithstock
#: code:addons/stock_picking_fillwithstock/models/stock.py:33
#, python-format
msgid "Please choose a source end location"
msgstr "Veuillez choisir un emplacement source physique"
#. module: stock_picking_fillwithstock
#: model:ir.model,name:stock_picking_fillwithstock.model_stock_picking
msgid "Transfer"
msgstr "Transfert"

View File

@@ -1,238 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * stock_move_location
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \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: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__apply_putaway_strategy
msgid "Apply putaway strategy"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Apply putaway strategy for moving products"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Cancel"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__picking_id
msgid "Connected Picking"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__create_uid
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__create_uid
msgid "Created by"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__create_date
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__create_date
msgid "Created on"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__custom
msgid "Custom line"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__destination_location_id
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__destination_location_id
msgid "Destination Location"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__destination_location_disable
msgid "Destination Location Disable"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__display_name
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__display_name
msgid "Display Name"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__edit_locations
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Edit Locations"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__id
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__id
msgid "ID"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Immediate Transfer"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Inventory Details"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location____last_update
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line____last_update
msgid "Last Modified on"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__write_uid
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__write_uid
msgid "Last Updated by"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__write_date
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__write_date
msgid "Last Updated on"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__lot_id
msgid "Lot/Serial Number"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__max_quantity
msgid "Maximum available quantity"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__stock_move_location_line_ids
msgid "Move Location lines"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.stock_picking_type_kanban
msgid "Move On Hand"
msgstr ""
#. module: stock_move_location
#: model:ir.actions.act_window,name:stock_move_location.wiz_stock_move_location_action
#: model:ir.ui.menu,name:stock_move_location.menuitem_move_location
msgid "Move from location..."
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__move_location_wizard_id
msgid "Move location Wizard"
msgstr ""
#. module: stock_move_location
#: code:addons/stock_move_location/wizard/stock_move_location_line.py:72
#, python-format
msgid "Move quantity can not exceed max quantity or be negative"
msgstr ""
#. module: stock_move_location
#: model:ir.actions.act_window,name:stock_move_location.wiz_stock_quant_location_action
msgid "Move to location..."
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__origin_location_id
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__origin_location_id
msgid "Origin Location"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__origin_location_disable
msgid "Origin Location Disable"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_stock_move__location_move
msgid "Part of move location"
msgstr ""
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_stock_picking_type
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location__picking_type_id
msgid "Picking Type"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "Planned Transfer"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__product_id
msgid "Product"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__product_uom_id
msgid "Product Unit of Measure"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_wiz_stock_move_location_line__move_quantity
msgid "Quantity to move"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,field_description:stock_move_location.field_stock_picking_type__show_move_onhand
msgid "Show Move On hand stock"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,help:stock_move_location.field_stock_picking_type__show_move_onhand
msgid "Show a button 'Move On Hand' in the Inventory Dashboard to initiate the process to move the products in stock at the origin location."
msgstr ""
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_stock_move
msgid "Stock Move"
msgstr ""
#. module: stock_move_location
#: model_terms:ir.ui.view,arch_db:stock_move_location.view_wiz_stock_move_location_form_stock_move_location
msgid "UoM"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,help:stock_move_location.field_stock_move__location_move
msgid "Whether this move is a part of stock_location moves"
msgstr ""
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_wiz_stock_move_location
msgid "Wizard move location"
msgstr ""
#. module: stock_move_location
#: model:ir.model,name:stock_move_location.model_wiz_stock_move_location_line
msgid "Wizard move location line"
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,help:stock_move_location.field_wiz_stock_move_location__destination_location_disable
msgid "technical field to disable the edition of destination location."
msgstr ""
#. module: stock_move_location
#: model:ir.model.fields,help:stock_move_location.field_wiz_stock_move_location__origin_location_disable
msgid "technical field to disable the edition of origin location."
msgstr ""

View File

@@ -3,3 +3,4 @@
from . import stock_move
from . import stock_picking_type
from . import stock_picking

View File

@@ -0,0 +1,45 @@
# Copyright Jacques-Etienne Baudoux 2016 Camptocamp
# Copyright Iryna Vyshnevska 2020 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from odoo import _, models
from odoo.exceptions import UserError
class StockPicking(models.Model):
_inherit = 'stock.picking'
def button_fillwithstock(self):
# check source location has no children, i.e. we scanned a bin
self.ensure_one()
self._validate_picking()
context = {
'active_ids': self._get_movable_quants().ids,
'active_model': 'stock.quant',
'only_reserved_qty': True,
'planned': True,
}
move_wizard = self.env['wiz.stock.move.location'].with_context(context).create({
'destination_location_id' : self.location_dest_id.id,
'origin_location_id': self.location_id.id,
'picking_type_id': self.picking_type_id.id,
'picking_id': self.id,
})
move_wizard._onchange_destination_location_id()
move_wizard.action_move_location()
return True
def _validate_picking(self):
if self.location_id.child_ids:
raise UserError(_('Please choose a source end location'))
if self.move_lines:
raise UserError(_('Moves lines already exists'))
def _get_movable_quants(self):
return self.env['stock.quant'].search(
[
('location_id', '=', self.location_id.id),
('quantity', '>', 0.0),
]
)

View File

@@ -4,3 +4,5 @@
* Joan Sisquella <joan.sisquella@eficent.com>
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Jacques-Etienne Baudoux <je@bcim.be>
* Iryna Vyshnevska <i.vyshnevska@mobilunity.com>

View File

@@ -19,4 +19,14 @@ If you want to transfer a full quant:
If you go to the Inventory Dashboard you can see the button "Move from location"
in each of the picking types (only applicable to internal transfers). Press it
and you will be directed to the wizard.
and you will be directed to the wizard.
If you want transfer everything from stock.location
On a draft picking, add a button to fill with moves lines for all products in
the source destination. This allows to create a picking to move all the content
of a location. If some quants are not available (i.e. reserved) the picking
will be in partially available state and reserved moves won't be listed in the
operations.
Use barcode interface to scan a location and create an empty picking. Then use
the fill with stock button.

View File

@@ -1,6 +1,3 @@
# Copyright (C) 2011 Julius Network Solutions SARL <contact@julius.fr>
# Copyright 2018 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from . import test_common
from . import test_move_location
from . import test_stock_fillwithstock

View File

@@ -0,0 +1,73 @@
# Copyright Iryna Vyshnevska 2020 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import odoo.tests.common as common
class TestFillwithStock(common.TransactionCase):
def setUp(self):
super(TestFillwithStock, self).setUp()
self.env = self.env(context=dict(
self.env.context,
tracking_disable=True,
))
self.stock_location = self.env.ref('stock.stock_location_stock')
self.pack_location = self.env.ref('stock.location_pack_zone')
self.shelf1_location = self.env["stock.location"].create({
"name": "Test location",
"usage": "internal",
"location_id": self.stock_location.id
})
self.product1 = self.env['product.product'].create({
'name': 'Product A',
'type': 'product',
})
self.product2 = self.env['product.product'].create({
'name': 'Product B',
'type': 'product',
})
self.env['stock.quant'].create({
'product_id': self.product1.id,
'location_id': self.shelf1_location.id,
'quantity': 5.0,
'reserved_quantity': 0.0,
})
self.env['stock.quant'].create({
'product_id': self.product1.id,
'location_id': self.shelf1_location.id,
'quantity': 10.0,
'reserved_quantity': 5.0,
})
self.env['stock.quant'].create({
'product_id': self.product2.id,
'location_id': self.shelf1_location.id,
'quantity': 5.0,
'reserved_quantity': 0.0,
})
def test_fillwithstock(self):
picking_stock_pack = self.env['stock.picking'].create({
'location_id': self.shelf1_location.id,
'location_dest_id': self.pack_location.id,
'picking_type_id': self.env.ref('stock.picking_type_internal').id,
})
self.assertFalse(picking_stock_pack.move_lines)
picking_stock_pack.button_fillwithstock()
# picking filled with quants in bin
self.assertEqual(len(picking_stock_pack.move_lines), 2)
self.assertEqual(
picking_stock_pack.move_lines.filtered(
lambda m: m.product_id == self.product1).product_uom_qty,
10.0
)
self.assertEqual(
picking_stock_pack.move_lines.filtered(
lambda m: m.product_id == self.product2).product_uom_qty,
5.0
)

View File

@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<odoo>
<record id="view_picking_form" model="ir.ui.view">
<field name="name">stock.picking.form.fillwithstock</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<button name="action_confirm" position="before">
<button name="button_fillwithstock" states="draft" string="Fill with stock" type="object" class="oe_highlight" groups="stock.group_stock_user" />
</button>
</field>
</record>
</odoo>

View File

@@ -5,6 +5,7 @@
from odoo import api, fields, models
from odoo.fields import first
from itertools import groupby
class StockMoveLocationWizard(models.TransientModel):
@@ -77,18 +78,45 @@ class StockMoveLocationWizard(models.TransientModel):
# Load data directly from quants
quants = self.env['stock.quant'].browse(
self.env.context.get('active_ids', False))
res['stock_move_location_line_ids'] = [(0, 0, {
'product_id': quant.product_id.id,
'move_quantity': quant.quantity,
'max_quantity': quant.quantity,
'origin_location_id': quant.location_id.id,
'lot_id': quant.lot_id.id,
'product_uom_id': quant.product_uom_id.id,
'custom': False,
}) for quant in quants]
res['stock_move_location_line_ids'] = self._prepare_wizard_move_lines(quants)
res['origin_location_id'] = first(quants).location_id.id
return res
@api.model
def _prepare_wizard_move_lines(self, quants):
res = []
exclude_reserved_qty = self.env.context.get('only_reserved_qty', False)
if not exclude_reserved_qty:
res = [(0, 0, {
'product_id': quant.product_id.id,
'move_quantity': quant.quantity,
'max_quantity': quant.quantity,
'origin_location_id': quant.location_id.id,
'lot_id': quant.lot_id.id,
'product_uom_id': quant.product_uom_id.id,
'custom': False,
}) for quant in quants]
else:
# if need move only available qty per product on location
for product, quant in groupby(quants, lambda r: r.product_id):
# we need only one quant per product
quant = list(quant)[0]
qty = quant._get_available_quantity(
quant.product_id,
quant.location_id,
)
if qty:
res.append((0, 0, {
'product_id': quant.product_id.id,
'move_quantity': qty,
'max_quantity': qty,
'origin_location_id': quant.location_id.id,
'lot_id': quant.lot_id.id,
'product_uom_id': quant.product_uom_id.id,
'custom': False,
}))
return res
@api.onchange('origin_location_id')
def _onchange_origin_location_id(self):
if not self.env.context.get('origin_location_disable', False):
@@ -167,7 +195,10 @@ class StockMoveLocationWizard(models.TransientModel):
@api.multi
def action_move_location(self):
self.ensure_one()
picking = self._create_picking()
if not self.picking_id:
picking = self._create_picking()
else:
picking = self.picking_id
self._create_moves(picking)
if not self.env.context.get("planned"):
picking.button_validate()