[IMP] add posibility to move only not reserved quantity

This commit is contained in:
Iryna Vushnevska
2020-04-23 16:10:14 +03:00
committed by Alex Cuellar
parent a82296d5e1
commit f915073acd
5 changed files with 152 additions and 89 deletions

View File

@@ -7,9 +7,9 @@
"name": "Move Stock Location",
"version": "15.0.1.0.0",
"author": "Julius Network Solutions, "
"BCIM,"
"Camptocamp,"
"Odoo Community Association (OCA)",
"BCIM,"
"Camptocamp,"
"Odoo Community Association (OCA)",
"summary": "This module allows to move all stock "
"in a stock location to an other one.",
"website": "https://github.com/OCA/stock-logistics-warehouse",
@@ -20,8 +20,8 @@
"data/stock_quant_view.xml",
"security/ir.model.access.csv",
"views/stock_picking_type_views.xml",
'views/stock_picking.xml',
'wizard/stock_move_location.xml',
"views/stock_picking.xml",
"wizard/stock_move_location.xml",
],
"post_init_hook": "enable_multi_locations",
}

View File

@@ -4,11 +4,10 @@
from odoo import _, models
from odoo.exceptions import UserError
from itertools import groupby
class StockPicking(models.Model):
_inherit = 'stock.picking'
_inherit = "stock.picking"
def button_fillwithstock(self):
# check source location has no children, i.e. we scanned a bin
@@ -16,31 +15,37 @@ class StockPicking(models.Model):
self.ensure_one()
self._validate_picking()
context = {
'active_ids': self._get_movable_quants().ids,
'active_model': 'stock.quant',
'only_reserved_qty': True,
'planned': True,
"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 = (
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'))
raise UserError(_("Please choose a source end location"))
if self.move_lines:
raise UserError(_('Moves lines already exists'))
raise UserError(_("Moves lines already exists"))
def _get_movable_quants(self):
return self.env['stock.quant'].search(
return self.env["stock.quant"].search(
[
('location_id', '=', self.location_id.id),
('quantity', '>', 0.0),
("location_id", "=", self.location_id.id),
("quantity", ">", 0.0),
]
)

View File

@@ -6,68 +6,85 @@ 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.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.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.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.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,
})
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,
})
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
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
lambda m: m.product_id == self.product2
).product_uom_qty,
5.0,
)

View File

@@ -1,13 +1,20 @@
<?xml version="1.0"?>
<?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="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
name="button_fillwithstock"
states="draft"
string="Fill with stock"
type="object"
class="oe_highlight"
groups="stock.group_stock_user"
/>
</button>
</field>
</record>

View File

@@ -3,6 +3,8 @@
# Copyright 2019 Sergio Teruel - Tecnativa <sergio.teruel@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
from itertools import groupby
from odoo import api, fields, models
from odoo.fields import first
@@ -82,26 +84,58 @@ class StockMoveLocationWizard(models.TransientModel):
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,
"reserved_quantity": quant.reserved_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):