diff --git a/setup/stock_account_inventory_discrepancy/odoo/addons/stock_account_inventory_discrepancy b/setup/stock_account_inventory_discrepancy/odoo/addons/stock_account_inventory_discrepancy
new file mode 120000
index 000000000..b805695ab
--- /dev/null
+++ b/setup/stock_account_inventory_discrepancy/odoo/addons/stock_account_inventory_discrepancy
@@ -0,0 +1 @@
+../../../../stock_account_inventory_discrepancy
\ No newline at end of file
diff --git a/setup/stock_account_inventory_discrepancy/setup.py b/setup/stock_account_inventory_discrepancy/setup.py
new file mode 100644
index 000000000..28c57bb64
--- /dev/null
+++ b/setup/stock_account_inventory_discrepancy/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)
diff --git a/stock_account_inventory_discrepancy/__manifest__.py b/stock_account_inventory_discrepancy/__manifest__.py
index b051910e2..d27c89ca3 100644
--- a/stock_account_inventory_discrepancy/__manifest__.py
+++ b/stock_account_inventory_discrepancy/__manifest__.py
@@ -3,11 +3,10 @@
{
"name": "Stock Account Inventory Discrepancy",
"summary": "Adds the capability to show the value discrepancy of every "
- "line in an inventory and to block the inventory validation "
- "when the discrepancy is over a user defined threshold.",
+ "line in an inventory and to block the inventory validation "
+ "when the discrepancy is over a user defined threshold.",
"version": "12.0.1.0.0",
- "author": "ForgeFlow, "
- "Odoo Community Association (OCA)",
+ "author": "ForgeFlow, " "Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"category": "Warehouse",
"depends": ["stock_inventory_discrepancy"],
diff --git a/stock_account_inventory_discrepancy/models/stock_inventory_line.py b/stock_account_inventory_discrepancy/models/stock_inventory_line.py
index 1da4843e8..ea4d49563 100644
--- a/stock_account_inventory_discrepancy/models/stock_inventory_line.py
+++ b/stock_account_inventory_discrepancy/models/stock_inventory_line.py
@@ -1,9 +1,10 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
-from odoo.addons import decimal_precision as dp
from odoo import api, fields, models
+from odoo.addons import decimal_precision as dp
+
class StockInventoryLine(models.Model):
_inherit = "stock.inventory.line"
@@ -13,13 +14,16 @@ class StockInventoryLine(models.Model):
compute="_compute_discrepancy_amount",
currency_field="company_currency_id",
help="The difference between the actual qty counted and the "
- "theoretical quantity on hand expressed in the cost amount.",
- digits=dp.get_precision("Product Unit of Measure"), default=0)
+ "theoretical quantity on hand expressed in the cost amount.",
+ digits=dp.get_precision("Product Unit of Measure"),
+ default=0,
+ )
discrepancy_amount_threshold = fields.Monetary(
string="Amount Threshold",
currency_field="company_currency_id",
help="Maximum Discrepancy Amount Threshold",
- compute="_compute_discrepancy_amount_threshold")
+ compute="_compute_discrepancy_amount_threshold",
+ )
company_currency_id = fields.Many2one(
string="Company Currency",
comodel_name="res.currency",
@@ -40,16 +44,17 @@ class StockInventoryLine(models.Model):
for line in self:
whs = line.location_id.get_warehouse()
if line.location_id.discrepancy_amount_threshold > 0.0:
- line.discrepancy_amount_threshold = line.location_id.\
- discrepancy_amount_threshold
+ line.discrepancy_amount_threshold = (
+ line.location_id.discrepancy_amount_threshold
+ )
elif whs.discrepancy_amount_threshold > 0.0:
- line.discrepancy_amount_threshold = \
- whs.discrepancy_amount_threshold
+ line.discrepancy_amount_threshold = whs.discrepancy_amount_threshold
else:
line.discrepancy_amount_threshold = False
@api.multi
def _has_over_discrepancy(self):
res = super()._has_over_discrepancy()
- return res or abs(
- self.discrepancy_amount) > self.discrepancy_amount_threshold > 0
+ return (
+ res or abs(self.discrepancy_amount) > self.discrepancy_amount_threshold > 0
+ )
diff --git a/stock_account_inventory_discrepancy/models/stock_location.py b/stock_account_inventory_discrepancy/models/stock_location.py
index dcfa0ab39..cee529ea4 100644
--- a/stock_account_inventory_discrepancy/models/stock_location.py
+++ b/stock_account_inventory_discrepancy/models/stock_location.py
@@ -11,11 +11,9 @@ class StockLocation(models.Model):
string="Maximum Discrepancy Amount Threshold",
currency_field="discrepancy_amount_threshold_currency_id",
help="Maximum Discrepancy Amount allowed for any product when doing "
- "an Inventory Adjustment. Thresholds defined in Locations have "
- "preference over Warehouse's ones.",
+ "an Inventory Adjustment. Thresholds defined in Locations have "
+ "preference over Warehouse's ones.",
)
discrepancy_amount_threshold_currency_id = fields.Many2one(
- comodel_name="res.currency",
- related="company_id.currency_id",
- readonly=True,
+ comodel_name="res.currency", related="company_id.currency_id", readonly=True,
)
diff --git a/stock_account_inventory_discrepancy/models/stock_warehouse.py b/stock_account_inventory_discrepancy/models/stock_warehouse.py
index afde72ae6..e756d8174 100644
--- a/stock_account_inventory_discrepancy/models/stock_warehouse.py
+++ b/stock_account_inventory_discrepancy/models/stock_warehouse.py
@@ -11,11 +11,9 @@ class StockWarehouse(models.Model):
string="Maximum Discrepancy Amount Threshold",
currency_field="discrepancy_amount_threshold_currency_id",
help="Maximum Discrepancy Amount allowed for any product when doing "
- "an Inventory Adjustment. Threshold defined in involved Location "
- "has preference.",
+ "an Inventory Adjustment. Threshold defined in involved Location "
+ "has preference.",
)
discrepancy_amount_threshold_currency_id = fields.Many2one(
- comodel_name="res.currency",
- related="company_id.currency_id",
- readonly=True,
+ comodel_name="res.currency", related="company_id.currency_id", readonly=True,
)
diff --git a/stock_account_inventory_discrepancy/tests/test_inventory_discrepancy.py b/stock_account_inventory_discrepancy/tests/test_inventory_discrepancy.py
index de69e32d4..cd94c365c 100644
--- a/stock_account_inventory_discrepancy/tests/test_inventory_discrepancy.py
+++ b/stock_account_inventory_discrepancy/tests/test_inventory_discrepancy.py
@@ -1,8 +1,8 @@
# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
-from odoo.tests.common import TransactionCase
from odoo.exceptions import UserError
+from odoo.tests.common import TransactionCase
class TestInventoryDiscrepancy(TransactionCase):
@@ -15,114 +15,143 @@ class TestInventoryDiscrepancy(TransactionCase):
self.obj_warehouse = self.env["stock.warehouse"]
self.obj_upd_qty_wizard = self.env["stock.change.product.qty"]
- self.product1 = self.obj_product.create({
- "name": "Test Product 1",
- "type": "product",
- "default_code": "PROD1",
- "standard_price": 110.0,
- })
- self.product2 = self.obj_product.create({
- "name": "Test Product 2",
- "type": "product",
- "default_code": "PROD2",
- "standard_price": 150.0,
- })
- self.test_loc = self.obj_location.create({
- "name": "Test Location",
- "usage": "internal",
- "discrepancy_amount_threshold": 100,
- })
- self.test_wh = self.obj_warehouse.create({
- "name": "Test WH",
- "code": "T",
- "discrepancy_amount_threshold": 300,
- })
+ self.product1 = self.obj_product.create(
+ {
+ "name": "Test Product 1",
+ "type": "product",
+ "default_code": "PROD1",
+ "standard_price": 110.0,
+ }
+ )
+ self.product2 = self.obj_product.create(
+ {
+ "name": "Test Product 2",
+ "type": "product",
+ "default_code": "PROD2",
+ "standard_price": 150.0,
+ }
+ )
+ self.test_loc = self.obj_location.create(
+ {
+ "name": "Test Location",
+ "usage": "internal",
+ "discrepancy_amount_threshold": 100,
+ }
+ )
+ self.test_wh = self.obj_warehouse.create(
+ {"name": "Test WH", "code": "T", "discrepancy_amount_threshold": 300,}
+ )
self.obj_location._parent_store_compute()
# Create Stock manager able to force validation on inventories.
group_stock_man = self.env.ref("stock.group_stock_manager")
group_inventory_all = self.env.ref(
- "stock_inventory_discrepancy."
- "group_stock_inventory_validation_always")
- self.manager = self.env["res.users"].create({
- "name": "Test Manager",
- "login": "manager",
- "email": "test.manager@example.com",
- "groups_id": [(6, 0, [group_stock_man.id, group_inventory_all.id])]
- })
+ "stock_inventory_discrepancy." "group_stock_inventory_validation_always"
+ )
+ self.manager = self.env["res.users"].create(
+ {
+ "name": "Test Manager",
+ "login": "manager",
+ "email": "test.manager@example.com",
+ "groups_id": [(6, 0, [group_stock_man.id, group_inventory_all.id])],
+ }
+ )
group_stock_user = self.env.ref("stock.group_stock_user")
- self.user = self.env["res.users"].create({
- "name": "Test User",
- "login": "user",
- "email": "test.user@example.com",
- "groups_id": [(6, 0, [group_stock_user.id])]
- })
+ self.user = self.env["res.users"].create(
+ {
+ "name": "Test User",
+ "login": "user",
+ "email": "test.user@example.com",
+ "groups_id": [(6, 0, [group_stock_user.id])],
+ }
+ )
- starting_inv = self.obj_inventory.create({
- "name": "Starting inventory",
- "filter": "product",
- "line_ids": [
- (0, 0, {
- "product_id": self.product1.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 2.0,
- "location_id": self.test_loc.id,
- }),
- (0, 0, {
- "product_id": self.product2.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 4.0,
- "location_id": self.test_loc.id,
- }),
- ],
- })
+ starting_inv = self.obj_inventory.create(
+ {
+ "name": "Starting inventory",
+ "filter": "product",
+ "line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product1.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 2.0,
+ "location_id": self.test_loc.id,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product2.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 4.0,
+ "location_id": self.test_loc.id,
+ },
+ ),
+ ],
+ }
+ )
starting_inv.action_force_done()
def test_compute_discrepancy(self):
"""Tests if the amount discrepancy is correctly computed.
"""
- inventory = self.obj_inventory.create({
- "name": "Test Discrepancy Computation",
- "location_id": self.test_loc.id,
- "filter": "none",
- "line_ids": [
- (0, 0, {
- "product_id": self.product1.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 3.0,
- "location_id": self.test_loc.id,
- }),
- (0, 0, {
- "product_id": self.product2.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 3.0,
- "location_id": self.test_loc.id,
- })
- ],
- })
+ inventory = self.obj_inventory.create(
+ {
+ "name": "Test Discrepancy Computation",
+ "location_id": self.test_loc.id,
+ "filter": "none",
+ "line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product1.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 3.0,
+ "location_id": self.test_loc.id,
+ },
+ ),
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product2.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 3.0,
+ "location_id": self.test_loc.id,
+ },
+ ),
+ ],
+ }
+ )
self.assertEqual(inventory.line_ids[0].discrepancy_amount, 110.0)
- self.assertEqual(inventory.line_ids[1].discrepancy_amount, - 150.0)
+ self.assertEqual(inventory.line_ids[1].discrepancy_amount, -150.0)
def test_amount_discrepancy_validation(self):
"""Tests the workflow with amount threshold."""
- inventory = self.obj_inventory.create({
- "name": "Test Forcing Validation Method",
- "location_id": self.test_loc.id,
- "filter": "none",
- "line_ids": [
- (0, 0, {
- "product_id": self.product1.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 3.0,
- "location_id": self.test_loc.id,
- }),
- ],
- })
+ inventory = self.obj_inventory.create(
+ {
+ "name": "Test Forcing Validation Method",
+ "location_id": self.test_loc.id,
+ "filter": "none",
+ "line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product1.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 3.0,
+ "location_id": self.test_loc.id,
+ },
+ ),
+ ],
+ }
+ )
self.assertEqual(inventory.state, "draft")
self.assertEqual(inventory.line_ids.discrepancy_amount_threshold, 100)
self.assertTrue(inventory.line_ids[0].has_over_discrepancy)
@@ -132,31 +161,38 @@ class TestInventoryDiscrepancy(TransactionCase):
def test_warehouse_amount_threshold(self):
"""Tests the behaviour if the threshold is set on the WH."""
- inventory = self.obj_inventory.create({
- "name": "Test Threshold Defined in WH",
- "location_id": self.test_wh.view_location_id.id,
- "filter": "none",
- "line_ids": [
- (0, 0, {
- "product_id": self.product1.id,
- "product_uom_id": self.env.ref(
- "uom.product_uom_unit").id,
- "product_qty": 3.0,
- "location_id": self.test_wh.lot_stock_id.id,
- }),
- ],
- })
+ inventory = self.obj_inventory.create(
+ {
+ "name": "Test Threshold Defined in WH",
+ "location_id": self.test_wh.view_location_id.id,
+ "filter": "none",
+ "line_ids": [
+ (
+ 0,
+ 0,
+ {
+ "product_id": self.product1.id,
+ "product_uom_id": self.env.ref("uom.product_uom_unit").id,
+ "product_qty": 3.0,
+ "location_id": self.test_wh.lot_stock_id.id,
+ },
+ ),
+ ],
+ }
+ )
self.assertEqual(inventory.line_ids.discrepancy_amount_threshold, 300)
def test_update_qty_user_error_amount(self):
"""Test if a user error raises when a stock user tries to update the
qty for a product and the correction is a discrepancy over the
threshold."""
- upd_qty = self.obj_upd_qty_wizard.sudo(self.user).create({
- "product_id": self.product1.id,
- "product_tmpl_id": self.product1.product_tmpl_id.id,
- "new_quantity": 10.0,
- "location_id": self.test_loc.id,
- })
+ upd_qty = self.obj_upd_qty_wizard.sudo(self.user).create(
+ {
+ "product_id": self.product1.id,
+ "product_tmpl_id": self.product1.product_tmpl_id.id,
+ "new_quantity": 10.0,
+ "location_id": self.test_loc.id,
+ }
+ )
with self.assertRaises(UserError):
upd_qty.change_product_qty()
diff --git a/stock_account_inventory_discrepancy/views/stock_inventory_view.xml b/stock_account_inventory_discrepancy/views/stock_inventory_view.xml
index af428534f..46c1e092c 100644
--- a/stock_account_inventory_discrepancy/views/stock_inventory_view.xml
+++ b/stock_account_inventory_discrepancy/views/stock_inventory_view.xml
@@ -1,21 +1,22 @@
-
+
-
-
- stock.inventory.form - stock_account_inventory_discrepancy
+ stock.inventory.form - stock_account_inventory_discrepancy
stock.inventory
-
+
-
-
-
-
+
+
+
+
-
diff --git a/stock_account_inventory_discrepancy/views/stock_location_view.xml b/stock_account_inventory_discrepancy/views/stock_location_view.xml
index bd2b58239..120b391c4 100644
--- a/stock_account_inventory_discrepancy/views/stock_location_view.xml
+++ b/stock_account_inventory_discrepancy/views/stock_location_view.xml
@@ -1,22 +1,24 @@
-
+
-
-
- stock.location.form - stock_account_inventory_discrepancy
+ stock.location.form - stock_account_inventory_discrepancy
stock.location
-
+
-
+
-
-
+
+
-
diff --git a/stock_account_inventory_discrepancy/views/stock_warehouse_view.xml b/stock_account_inventory_discrepancy/views/stock_warehouse_view.xml
index f7124fe1f..252bd6cf6 100644
--- a/stock_account_inventory_discrepancy/views/stock_warehouse_view.xml
+++ b/stock_account_inventory_discrepancy/views/stock_warehouse_view.xml
@@ -1,22 +1,22 @@
-
+
-
-
stock.warehouse - stock_account_inventory_discrepancy
stock.warehouse
-
+
-
+
-
-
+
+
-