[IMP] : black, isort, prettier

This commit is contained in:
Lois Rilo
2021-06-11 13:29:11 +02:00
parent 9ffd15b298
commit 88717bdc08
10 changed files with 211 additions and 165 deletions

View File

@@ -0,0 +1 @@
../../../../stock_account_inventory_discrepancy

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

View File

@@ -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"],

View File

@@ -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
)

View File

@@ -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,
)

View File

@@ -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,
)

View File

@@ -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()

View File

@@ -1,21 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_inventory_form" model="ir.ui.view">
<field name="name">stock.inventory.form - stock_account_inventory_discrepancy</field>
<field
name="name"
>stock.inventory.form - stock_account_inventory_discrepancy</field>
<field name="model">stock.inventory</field>
<field name="inherit_id" ref="stock.view_inventory_form"/>
<field name="inherit_id" ref="stock.view_inventory_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='line_ids']/tree/field[@name='product_qty']"
position="after">
<field name="discrepancy_amount"/>
<field name="discrepancy_amount_threshold"/>
<field name="company_currency_id" invisible="1" readonly="1"/>
<xpath
expr="//field[@name='line_ids']/tree/field[@name='product_qty']"
position="after"
>
<field name="discrepancy_amount" />
<field name="discrepancy_amount_threshold" />
<field name="company_currency_id" invisible="1" readonly="1" />
</xpath>
</field>
</record>
</odoo>

View File

@@ -1,22 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_location_form" model="ir.ui.view">
<field name="name">stock.location.form - stock_account_inventory_discrepancy</field>
<field
name="name"
>stock.location.form - stock_account_inventory_discrepancy</field>
<field name="model">stock.location</field>
<field name="inherit_id" ref="stock.view_location_form"/>
<field name="inherit_id" ref="stock.view_location_form" />
<field name="arch" type="xml">
<field name="partner_id" position="after">
<label for="discrepancy_amount_threshold"/>
<label for="discrepancy_amount_threshold" />
<div>
<field name="discrepancy_amount_threshold" class="oe_inline"/>
<field name="discrepancy_amount_threshold_currency_id" invisible="1"/>
<field name="discrepancy_amount_threshold" class="oe_inline" />
<field
name="discrepancy_amount_threshold_currency_id"
invisible="1"
/>
</div>
</field>
</field>
</record>
</odoo>

View File

@@ -1,22 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_warehouse" model="ir.ui.view">
<field name="name">stock.warehouse - stock_account_inventory_discrepancy</field>
<field name="model">stock.warehouse</field>
<field name="inherit_id" ref="stock.view_warehouse"/>
<field name="inherit_id" ref="stock.view_warehouse" />
<field name="arch" type="xml">
<field name="partner_id" position="after">
<label for="discrepancy_amount_threshold"/>
<label for="discrepancy_amount_threshold" />
<div>
<field name="discrepancy_amount_threshold"/>
<field name="discrepancy_amount_threshold_currency_id" invisible="1"/>
<field name="discrepancy_amount_threshold" />
<field
name="discrepancy_amount_threshold_currency_id"
invisible="1"
/>
</div>
</field>
</field>
</record>
</odoo>