mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_change_qty_reason: black, isort
This commit is contained in:
committed by
GuillemCForgeFlow
parent
9245c4ad61
commit
82cf7c8244
@@ -2,25 +2,23 @@
|
|||||||
# Copyright 2019 Eficent Business and IT Consulting Services S.L.
|
# Copyright 2019 Eficent Business and IT Consulting Services S.L.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
{
|
{
|
||||||
'name': "Stock Change Quantity Reason",
|
"name": "Stock Change Quantity Reason",
|
||||||
'summary': """
|
"summary": """
|
||||||
Stock Quantity Change Reason """,
|
Stock Quantity Change Reason """,
|
||||||
'author': 'ACSONE SA/NV, Odoo Community Association (OCA)',
|
"author": "ACSONE SA/NV, Odoo Community Association (OCA)",
|
||||||
'website': "https://github.com/OCA/stock-logistics-warehouse",
|
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||||
'category': 'Warehouse Management',
|
"category": "Warehouse Management",
|
||||||
'version': '12.0.1.0.0',
|
"version": "12.0.1.0.0",
|
||||||
'license': 'AGPL-3',
|
"license": "AGPL-3",
|
||||||
'depends': [
|
"depends": ["stock"],
|
||||||
'stock',
|
"data": [
|
||||||
|
"security/ir.model.access.csv",
|
||||||
|
"security/stock_security.xml",
|
||||||
|
"views/base_config_view.xml",
|
||||||
|
"views/stock_inventory_line_reason_view.xml",
|
||||||
|
"views/stock_inventory_line_view.xml",
|
||||||
|
"views/stock_inventory_view.xml",
|
||||||
|
"wizard/stock_product_change_qty.xml",
|
||||||
],
|
],
|
||||||
'data': [
|
"installable": True,
|
||||||
'security/ir.model.access.csv',
|
|
||||||
'security/stock_security.xml',
|
|
||||||
'views/base_config_view.xml',
|
|
||||||
'views/stock_inventory_line_reason_view.xml',
|
|
||||||
'views/stock_inventory_line_view.xml',
|
|
||||||
'views/stock_inventory_view.xml',
|
|
||||||
'wizard/stock_product_change_qty.xml'
|
|
||||||
],
|
|
||||||
'installable': True,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ from odoo import fields, models
|
|||||||
|
|
||||||
|
|
||||||
class ResConfigSettings(models.TransientModel):
|
class ResConfigSettings(models.TransientModel):
|
||||||
_inherit = 'res.config.settings'
|
_inherit = "res.config.settings"
|
||||||
|
|
||||||
group_qty_reason_preset = fields.Boolean(
|
group_qty_reason_preset = fields.Boolean(
|
||||||
string="Preset Change Qty Reason",
|
string="Preset Change Qty Reason",
|
||||||
required=True,
|
required=True,
|
||||||
implied_group='stock_change_qty_reason.group_qty_reason_preset',
|
implied_group="stock_change_qty_reason.group_qty_reason_preset",
|
||||||
help="Enable use of predefined Reasons to manage Inventory Adjustments"
|
help="Enable use of predefined Reasons to manage Inventory Adjustments"
|
||||||
"and Product Update Quantities Wizard.")
|
"and Product Update Quantities Wizard.",
|
||||||
|
)
|
||||||
|
|||||||
@@ -4,27 +4,26 @@ from odoo import api, fields, models
|
|||||||
|
|
||||||
|
|
||||||
class StockInventory(models.Model):
|
class StockInventory(models.Model):
|
||||||
_inherit = 'stock.inventory'
|
_inherit = "stock.inventory"
|
||||||
|
|
||||||
reason = fields.Char(help='Type in a reason for the '
|
reason = fields.Char(help="Type in a reason for the " "product quantity change")
|
||||||
'product quantity change')
|
preset_reason_id = fields.Many2one("stock.inventory.line.reason")
|
||||||
preset_reason_id = fields.Many2one('stock.inventory.line.reason')
|
|
||||||
|
|
||||||
def _get_inventory_lines_values(self):
|
def _get_inventory_lines_values(self):
|
||||||
vals = super(StockInventory, self)._get_inventory_lines_values()
|
vals = super(StockInventory, self)._get_inventory_lines_values()
|
||||||
for val in vals:
|
for val in vals:
|
||||||
if self.preset_reason_id:
|
if self.preset_reason_id:
|
||||||
val['preset_reason_id'] = self.preset_reason_id.id
|
val["preset_reason_id"] = self.preset_reason_id.id
|
||||||
elif self.reason:
|
elif self.reason:
|
||||||
val['reason'] = self.reason
|
val["reason"] = self.reason
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
@api.onchange('reason')
|
@api.onchange("reason")
|
||||||
def onchange_reason(self):
|
def onchange_reason(self):
|
||||||
for line in self.line_ids:
|
for line in self.line_ids:
|
||||||
line.reason = self.reason
|
line.reason = self.reason
|
||||||
|
|
||||||
@api.onchange('preset_reason_id')
|
@api.onchange("preset_reason_id")
|
||||||
def onchange_preset_reason(self):
|
def onchange_preset_reason(self):
|
||||||
for line in self.line_ids:
|
for line in self.line_ids:
|
||||||
line.preset_reason_id = self.preset_reason_id
|
line.preset_reason_id = self.preset_reason_id
|
||||||
|
|||||||
@@ -6,23 +6,26 @@ from odoo import fields, models
|
|||||||
|
|
||||||
class StockInventoryLine(models.Model):
|
class StockInventoryLine(models.Model):
|
||||||
"""Class to inherit model stock.inventory.line"""
|
"""Class to inherit model stock.inventory.line"""
|
||||||
|
|
||||||
_inherit = "stock.inventory.line"
|
_inherit = "stock.inventory.line"
|
||||||
|
|
||||||
reason = fields.Char(help='Type in a reason for the '
|
reason = fields.Char(help="Type in a reason for the " "product quantity change")
|
||||||
'product quantity change')
|
preset_reason_id = fields.Many2one("stock.inventory.line.reason")
|
||||||
preset_reason_id = fields.Many2one('stock.inventory.line.reason')
|
|
||||||
|
|
||||||
def _get_move_values(self, qty, location_id, location_dest_id, out):
|
def _get_move_values(self, qty, location_id, location_dest_id, out):
|
||||||
"""Function to super _get_move_value"""
|
"""Function to super _get_move_value"""
|
||||||
res = super(StockInventoryLine, self)._get_move_values(
|
res = super(StockInventoryLine, self)._get_move_values(
|
||||||
qty, location_id, location_dest_id, out)
|
qty, location_id, location_dest_id, out
|
||||||
context = self.env.context.get(
|
)
|
||||||
'change_quantity_reason', False) or self.reason \
|
context = (
|
||||||
if not self.preset_reason_id else self.preset_reason_id.name
|
self.env.context.get("change_quantity_reason", False) or self.reason
|
||||||
if res.get('origin'):
|
if not self.preset_reason_id
|
||||||
res['origin'] = ' ,'.join([res.get('origin'), context])
|
else self.preset_reason_id.name
|
||||||
|
)
|
||||||
|
if res.get("origin"):
|
||||||
|
res["origin"] = " ,".join([res.get("origin"), context])
|
||||||
else:
|
else:
|
||||||
res['origin'] = context
|
res["origin"] = context
|
||||||
if self.preset_reason_id:
|
if self.preset_reason_id:
|
||||||
res['preset_reason_id'] = self.preset_reason_id.id
|
res["preset_reason_id"] = self.preset_reason_id.id
|
||||||
return res
|
return res
|
||||||
|
|||||||
@@ -5,14 +5,17 @@ from odoo import fields, models
|
|||||||
|
|
||||||
class StockInventoryLineReason(models.Model):
|
class StockInventoryLineReason(models.Model):
|
||||||
|
|
||||||
_name = 'stock.inventory.line.reason'
|
_name = "stock.inventory.line.reason"
|
||||||
_description = 'Stock Inventory Line Reason'
|
_description = "Stock Inventory Line Reason"
|
||||||
|
|
||||||
name = fields.Char('Reason Name')
|
name = fields.Char("Reason Name")
|
||||||
description = fields.Text('Reason Description')
|
description = fields.Text("Reason Description")
|
||||||
active = fields.Boolean(default=True)
|
active = fields.Boolean(default=True)
|
||||||
|
|
||||||
_sql_constraints = [
|
_sql_constraints = [
|
||||||
('name_unique', 'UNIQUE(name)',
|
(
|
||||||
'You cannot have two reason with the same name.'),
|
"name_unique",
|
||||||
|
"UNIQUE(name)",
|
||||||
|
"You cannot have two reason with the same name.",
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,5 +6,4 @@ from odoo import fields, models
|
|||||||
class StockMove(models.Model):
|
class StockMove(models.Model):
|
||||||
_inherit = "stock.move"
|
_inherit = "stock.move"
|
||||||
|
|
||||||
preset_reason_id = fields.Many2one('stock.inventory.line.reason',
|
preset_reason_id = fields.Many2one("stock.inventory.line.reason", required=False)
|
||||||
required=False)
|
|
||||||
|
|||||||
@@ -7,100 +7,83 @@ from odoo.tests.common import SavepointCase
|
|||||||
|
|
||||||
|
|
||||||
class TestStockQuantityChangeReason(SavepointCase):
|
class TestStockQuantityChangeReason(SavepointCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super(TestStockQuantityChangeReason, cls).setUpClass()
|
super(TestStockQuantityChangeReason, cls).setUpClass()
|
||||||
|
|
||||||
# MODELS
|
# MODELS
|
||||||
cls.stock_move = cls.env['stock.move']
|
cls.stock_move = cls.env["stock.move"]
|
||||||
cls.product_product_model = cls.env['product.product']
|
cls.product_product_model = cls.env["product.product"]
|
||||||
cls.product_category_model = cls.env['product.category']
|
cls.product_category_model = cls.env["product.category"]
|
||||||
cls.wizard_model = cls.env['stock.change.product.qty']
|
cls.wizard_model = cls.env["stock.change.product.qty"]
|
||||||
cls.preset_reason_id = cls.env['stock.inventory.line.reason']
|
cls.preset_reason_id = cls.env["stock.inventory.line.reason"]
|
||||||
cls.stock_location = cls.env.ref('stock.stock_location_stock')
|
cls.stock_location = cls.env.ref("stock.stock_location_stock")
|
||||||
|
|
||||||
# INSTANCES
|
# INSTANCES
|
||||||
cls.category = cls.product_category_model.create({
|
cls.category = cls.product_category_model.create({"name": "Physical (test)"})
|
||||||
'name': 'Physical (test)'})
|
|
||||||
|
|
||||||
def _create_product(self, name):
|
def _create_product(self, name):
|
||||||
return self.product_product_model.create({
|
return self.product_product_model.create(
|
||||||
'name': name,
|
{"name": name, "categ_id": self.category.id, "type": "product"}
|
||||||
'categ_id': self.category.id,
|
)
|
||||||
'type': 'product'})
|
|
||||||
|
|
||||||
def _product_change_qty(self, product, new_qty, reason,
|
def _product_change_qty(self, product, new_qty, reason, preset_reason_id=None):
|
||||||
preset_reason_id=None):
|
values = {"product_id": product.id, "new_quantity": new_qty, "reason": reason}
|
||||||
values = {
|
|
||||||
'product_id': product.id,
|
|
||||||
'new_quantity': new_qty,
|
|
||||||
'reason': reason,
|
|
||||||
}
|
|
||||||
if preset_reason_id:
|
if preset_reason_id:
|
||||||
values.update({'preset_reason_id': preset_reason_id.id})
|
values.update({"preset_reason_id": preset_reason_id.id})
|
||||||
wizard = self.wizard_model.create(values)
|
wizard = self.wizard_model.create(values)
|
||||||
wizard.change_product_qty()
|
wizard.change_product_qty()
|
||||||
|
|
||||||
def _create_reason(self, name, description=None):
|
def _create_reason(self, name, description=None):
|
||||||
return self.preset_reason_id.create({
|
return self.preset_reason_id.create({"name": name, "description": description})
|
||||||
'name': name,
|
|
||||||
'description': description})
|
|
||||||
|
|
||||||
def test_product_change_qty(self):
|
def test_product_change_qty(self):
|
||||||
""" Check product quantity update move reason is well set
|
""" Check product quantity update move reason is well set
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# create products
|
# create products
|
||||||
product2 = self._create_product('product_product_2')
|
product2 = self._create_product("product_product_2")
|
||||||
product3 = self._create_product('product_product_3')
|
product3 = self._create_product("product_product_3")
|
||||||
product4 = self._create_product('product_product_4')
|
product4 = self._create_product("product_product_4")
|
||||||
product5 = self._create_product('product_product_5')
|
product5 = self._create_product("product_product_5")
|
||||||
product6 = self._create_product('product_product_6')
|
product6 = self._create_product("product_product_6")
|
||||||
|
|
||||||
# update qty on hand and add reason
|
# update qty on hand and add reason
|
||||||
self._product_change_qty(product2, 10, 'product_2_reason')
|
self._product_change_qty(product2, 10, "product_2_reason")
|
||||||
self._product_change_qty(product3, 0, 'product_3_reason')
|
self._product_change_qty(product3, 0, "product_3_reason")
|
||||||
self._product_change_qty(product4, 0, 'product_4_reason')
|
self._product_change_qty(product4, 0, "product_4_reason")
|
||||||
self._product_change_qty(product5, 10, 'product_5_reason')
|
self._product_change_qty(product5, 10, "product_5_reason")
|
||||||
self._product_change_qty(product6, 0, 'product_6_reason')
|
self._product_change_qty(product6, 0, "product_6_reason")
|
||||||
|
|
||||||
# check stock moves created
|
# check stock moves created
|
||||||
move2 = self.stock_move.search([('product_id', '=',
|
move2 = self.stock_move.search([("product_id", "=", product2.id)])
|
||||||
product2.id)])
|
move3 = self.stock_move.search([("product_id", "=", product3.id)])
|
||||||
move3 = self.stock_move.search([('product_id', '=',
|
move4 = self.stock_move.search([("product_id", "=", product4.id)])
|
||||||
product3.id)])
|
move5 = self.stock_move.search([("product_id", "=", product5.id)])
|
||||||
move4 = self.stock_move.search([('product_id', '=',
|
move6 = self.stock_move.search([("product_id", "=", product6.id)])
|
||||||
product4.id)])
|
|
||||||
move5 = self.stock_move.search([('product_id', '=',
|
|
||||||
product5.id)])
|
|
||||||
move6 = self.stock_move.search([('product_id', '=',
|
|
||||||
product6.id)])
|
|
||||||
|
|
||||||
self.assertEqual(move2.origin, 'product_2_reason')
|
self.assertEqual(move2.origin, "product_2_reason")
|
||||||
self.assertFalse(move3)
|
self.assertFalse(move3)
|
||||||
self.assertFalse(move4)
|
self.assertFalse(move4)
|
||||||
self.assertEqual(move5.origin, 'product_5_reason')
|
self.assertEqual(move5.origin, "product_5_reason")
|
||||||
self.assertFalse(move6)
|
self.assertFalse(move6)
|
||||||
|
|
||||||
def test_product_change_qty_with_preset_reason(self):
|
def test_product_change_qty_with_preset_reason(self):
|
||||||
""" Check product quantity update move reason is well set
|
""" Check product quantity update move reason is well set
|
||||||
"""
|
"""
|
||||||
# create reason
|
# create reason
|
||||||
reason = self._create_reason('Test', 'Description Test')
|
reason = self._create_reason("Test", "Description Test")
|
||||||
# create products
|
# create products
|
||||||
product2 = self._create_product('product_product_2')
|
product2 = self._create_product("product_product_2")
|
||||||
product3 = self._create_product('product_product_3')
|
product3 = self._create_product("product_product_3")
|
||||||
|
|
||||||
# update qty on hand and add reason
|
# update qty on hand and add reason
|
||||||
self._product_change_qty(product2, 10, reason.name, reason)
|
self._product_change_qty(product2, 10, reason.name, reason)
|
||||||
self._product_change_qty(product3, 0, reason.name, reason)
|
self._product_change_qty(product3, 0, reason.name, reason)
|
||||||
|
|
||||||
# check stock moves created
|
# check stock moves created
|
||||||
move2 = self.stock_move.search([('product_id', '=',
|
move2 = self.stock_move.search([("product_id", "=", product2.id)])
|
||||||
product2.id)])
|
move3 = self.stock_move.search([("product_id", "=", product3.id)])
|
||||||
move3 = self.stock_move.search([('product_id', '=',
|
|
||||||
product3.id)])
|
|
||||||
# asserts
|
# asserts
|
||||||
self.assertEqual(move2.origin, reason.name)
|
self.assertEqual(move2.origin, reason.name)
|
||||||
self.assertEqual(move2.preset_reason_id, reason)
|
self.assertEqual(move2.preset_reason_id, reason)
|
||||||
@@ -109,24 +92,24 @@ class TestStockQuantityChangeReason(SavepointCase):
|
|||||||
def test_inventory_adjustment_onchange_reason_preset_reason(self):
|
def test_inventory_adjustment_onchange_reason_preset_reason(self):
|
||||||
""" Check that adding a reason or a preset reason explode to lines
|
""" Check that adding a reason or a preset reason explode to lines
|
||||||
"""
|
"""
|
||||||
product2 = self._create_product('product_product_2')
|
product2 = self._create_product("product_product_2")
|
||||||
self._product_change_qty(product2, 50, 'product_2_reason')
|
self._product_change_qty(product2, 50, "product_2_reason")
|
||||||
inventory = self.env['stock.inventory'].create({
|
inventory = self.env["stock.inventory"].create(
|
||||||
'name': 'remove product2',
|
{
|
||||||
'filter': 'product',
|
"name": "remove product2",
|
||||||
'location_id': self.stock_location.id,
|
"filter": "product",
|
||||||
'product_id': product2.id,
|
"location_id": self.stock_location.id,
|
||||||
})
|
"product_id": product2.id,
|
||||||
inventory.preset_reason_id = self._create_reason('Test 1',
|
}
|
||||||
'Description Test 1')
|
)
|
||||||
|
inventory.preset_reason_id = self._create_reason("Test 1", "Description Test 1")
|
||||||
inventory.action_start()
|
inventory.action_start()
|
||||||
self.assertEqual(len(inventory.line_ids), 1)
|
self.assertEqual(len(inventory.line_ids), 1)
|
||||||
inventory.preset_reason_id = self._create_reason('Test 2',
|
inventory.preset_reason_id = self._create_reason("Test 2", "Description Test 2")
|
||||||
'Description Test 2')
|
|
||||||
inventory.onchange_preset_reason()
|
inventory.onchange_preset_reason()
|
||||||
self.assertEquals(inventory.line_ids.preset_reason_id,
|
self.assertEquals(
|
||||||
inventory.preset_reason_id)
|
inventory.line_ids.preset_reason_id, inventory.preset_reason_id
|
||||||
inventory.reason = 'Reason 2'
|
)
|
||||||
|
inventory.reason = "Reason 2"
|
||||||
inventory.onchange_reason()
|
inventory.onchange_reason()
|
||||||
self.assertEquals(inventory.line_ids.reason,
|
self.assertEquals(inventory.line_ids.reason, inventory.reason)
|
||||||
inventory.reason)
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ from odoo import api, fields, models
|
|||||||
|
|
||||||
class StockChangeProductQty(models.TransientModel):
|
class StockChangeProductQty(models.TransientModel):
|
||||||
"""Class to inherit model stock.change.product.qty"""
|
"""Class to inherit model stock.change.product.qty"""
|
||||||
_inherit = 'stock.change.product.qty'
|
|
||||||
|
|
||||||
reason = fields.Char(help='Type in a reason for the '
|
_inherit = "stock.change.product.qty"
|
||||||
'product quantity change')
|
|
||||||
preset_reason_id = fields.Many2one('stock.inventory.line.reason')
|
reason = fields.Char(help="Type in a reason for the " "product quantity change")
|
||||||
|
preset_reason_id = fields.Many2one("stock.inventory.line.reason")
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def change_product_qty(self):
|
def change_product_qty(self):
|
||||||
@@ -23,13 +23,17 @@ class StockChangeProductQty(models.TransientModel):
|
|||||||
def _action_start_line(self):
|
def _action_start_line(self):
|
||||||
res = super(StockChangeProductQty, self)._action_start_line()
|
res = super(StockChangeProductQty, self)._action_start_line()
|
||||||
if self.preset_reason_id:
|
if self.preset_reason_id:
|
||||||
res.update({'preset_reason_id': self.preset_reason_id.id,
|
res.update(
|
||||||
'reason': self.preset_reason_id.name})
|
{
|
||||||
|
"preset_reason_id": self.preset_reason_id.id,
|
||||||
|
"reason": self.preset_reason_id.name,
|
||||||
|
}
|
||||||
|
)
|
||||||
elif self.reason:
|
elif self.reason:
|
||||||
res.update({'reason': self.reason})
|
res.update({"reason": self.reason})
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@api.onchange('preset_reason_id')
|
@api.onchange("preset_reason_id")
|
||||||
def onchange_preset_reason_id(self):
|
def onchange_preset_reason_id(self):
|
||||||
if self.preset_reason_id:
|
if self.preset_reason_id:
|
||||||
self.reason = self.preset_reason_id.name
|
self.reason = self.preset_reason_id.name
|
||||||
|
|||||||
Reference in New Issue
Block a user