Skip to content

Commit

Permalink
Merge PR #1991 into 15.0
Browse files Browse the repository at this point in the history
Signed-off-by LoisRForgeFlow
  • Loading branch information
OCA-git-bot committed Apr 23, 2024
2 parents 0348fbc + d446af6 commit 2783864
Show file tree
Hide file tree
Showing 11 changed files with 328 additions and 30 deletions.
2 changes: 2 additions & 0 deletions stock_inventory/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
"depends": ["stock"],
"data": [
"security/ir.model.access.csv",
"security/security.xml",
"views/stock_inventory.xml",
"views/stock_quant.xml",
"views/stock_move_line.xml",
"views/res_config_settings_view.xml",
],
"installable": True,
"application": False,
Expand Down
2 changes: 2 additions & 0 deletions stock_inventory/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from . import stock_inventory
from . import stock_quant
from . import stock_move_line
from . import res_company
from . import res_config_settings
15 changes: 15 additions & 0 deletions stock_inventory/models/res_company.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2024 ForgeFlow S.L. (http://www.forgeflow.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).


from odoo import fields, models


class ResCompany(models.Model):
_inherit = "res.company"

stock_inventory_auto_complete = fields.Boolean(
help="If enabled, when all the quants prepared for the adjustment "
"are done, the adjustment is automatically set to done.",
default=False,
)
12 changes: 12 additions & 0 deletions stock_inventory/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2024 ForgeFlow S.L. (http://www.forgeflow.com)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"

stock_inventory_auto_complete = fields.Boolean(
related="company_id.stock_inventory_auto_complete", readonly=False
)
143 changes: 119 additions & 24 deletions stock_inventory/models/stock_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,28 @@ class InventoryAdjustmentsGroup(models.Model):
_description = "Inventory Adjustment Group"
_order = "date desc, id desc"

name = fields.Char(required=True, default="Inventory", string="Inventory Reference")
name = fields.Char(
required=True,
default="Inventory",
string="Inventory Reference",
states={"draft": [("readonly", False)]},
readonly=True,
)

date = fields.Datetime(default=lambda self: fields.Datetime.now())
date = fields.Datetime(
default=lambda self: fields.Datetime.now(),
states={"draft": [("readonly", False)]},
readonly=True,
)

company_id = fields.Many2one(
comodel_name="res.company",
readonly=True,
index=True,
states={"draft": [("readonly", False)]},
default=lambda self: self.env.company,
required=True,
)

state = fields.Selection(
[("draft", "Draft"), ("in_progress", "In Progress"), ("done", "Done")],
Expand All @@ -22,7 +41,10 @@ class InventoryAdjustmentsGroup(models.Model):
)

location_ids = fields.Many2many(
"stock.location", string="Locations", domain="[('usage', '=', 'internal')]"
"stock.location",
string="Locations",
domain="[('usage', '=', 'internal'), "
"'|', ('company_id', '=', company_id), ('company_id', '=', False)]",
)

product_selection = fields.Selection(
Expand All @@ -37,15 +59,24 @@ class InventoryAdjustmentsGroup(models.Model):
required=True,
)

product_ids = fields.Many2many("product.product", string="Products")
product_ids = fields.Many2many(
"product.product",
string="Products",
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]",
)

stock_quant_ids = fields.Many2many("stock.quant", string="Inventory Adjustment")
stock_quant_ids = fields.Many2many(
"stock.quant",
string="Inventory Adjustment",
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]",
)

category_id = fields.Many2one("product.category", string="Product Category")

lot_ids = fields.Many2many(
"stock.production.lot",
string="Lot/Serial Numbers",
domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]",
)

stock_move_ids = fields.One2many(
Expand All @@ -66,14 +97,24 @@ class InventoryAdjustmentsGroup(models.Model):
compute="_compute_count_stock_moves", string="Stock Moves Lines"
)

exclude_sublocation = fields.Boolean(
help="If enabled, it will only take into account "
"the locations selected, and not their children."
)

responsible_id = fields.Many2one(
comodel_name="res.users",
string="Assigned to",
states={"draft": [("readonly", False)]},
readonly=True,
tracking=True,
help="Specific responsible of Inventory Adjustment.",
)

@api.depends("stock_quant_ids")
def _compute_count_stock_quants(self):
self.count_stock_quants = len(self.stock_quant_ids)
count_todo = len(
self.stock_quant_ids.search(
[("id", "in", self.stock_quant_ids.ids), ("to_do", "=", "True")]
)
)
count_todo = len(self.stock_quant_ids.filtered(lambda sq: sq.to_do))
self.count_stock_quants_string = "{} / {}".format(
count_todo, self.count_stock_quants
)
Expand All @@ -99,11 +140,15 @@ def _get_quants(self, locations):
return self.env["stock.quant"].search(domain)

def _get_base_domain(self, locations):
return [
"|",
("location_id", "in", locations.mapped("id")),
("location_id", "in", locations.child_ids.ids),
]
return (
[
("location_id", "in", locations.mapped("id")),
]
if self.exclude_sublocation
else [
("location_id", "child_of", locations.child_internal_location_ids.ids),
]
)

def _get_domain_all_quants(self, base_domain):
return base_domain
Expand Down Expand Up @@ -146,13 +191,15 @@ def _get_domain_category_quants(self, base_domain):
]
)

def refresh_stock_quant_ids(self):
for rec in self:
rec.stock_quant_ids = rec._get_quants(rec.location_ids)

def action_state_to_in_progress(self):
active_rec = self.env["stock.inventory"].search(
[
("state", "=", "in_progress"),
"|",
("location_ids", "in", self.location_ids.mapped("id")),
("location_ids", "in", self.location_ids.child_ids.ids),
("location_ids", "child_of", self.location_ids.ids),
],
limit=1,
)
Expand All @@ -164,25 +211,48 @@ def action_state_to_in_progress(self):
% active_rec.name
)
self.state = "in_progress"
self.stock_quant_ids = self._get_quants(self.location_ids)
self.stock_quant_ids.update({"to_do": True})
self.refresh_stock_quant_ids()
self.stock_quant_ids.update(
{
"to_do": True,
"user_id": self.responsible_id,
"inventory_date": self.date,
}
)
return

def action_state_to_done(self):
self.state = "done"
self.stock_quant_ids.update({"to_do": True})
self.stock_quant_ids.update(
{
"to_do": True,
"user_id": False,
"inventory_date": False,
}
)
return

def action_auto_state_to_done(self):
self.ensure_one()
if not any(self.stock_quant_ids.filtered(lambda sq: sq.to_do)):
self.action_state_to_done()
return

def action_state_to_draft(self):
self.state = "draft"
self.stock_quant_ids.update({"to_do": True})
self.stock_quant_ids.update(
{
"to_do": True,
"user_id": False,
"inventory_date": False,
}
)
self.stock_quant_ids = None
return

def action_view_inventory_adjustment(self):
result = self.env["stock.quant"].action_view_inventory()
ia_ids = self.mapped("stock_quant_ids").ids
result["domain"] = [("id", "in", ia_ids)]
result["domain"] = [("id", "in", self.stock_quant_ids.ids)]
result["search_view_id"] = self.env.ref("stock.quant_search_view").id
result["context"]["search_default_to_do"] = 1
return result
Expand All @@ -196,6 +266,31 @@ def action_view_stock_moves(self):
result["context"] = []
return result

@api.constrains("state", "location_ids")
def _check_inventory_in_progress_not_override(self):
inventories = self.search([("state", "=", "in_progress")])
for rec in inventories:
inventory = inventories.filtered(
lambda x: x.id != rec.id
and (
any(i in x.location_ids for i in rec.location_ids)
or (
any(
i in x.location_ids.child_internal_location_ids
for i in rec.location_ids
)
and not x.exclude_sublocation
)
)
)
if len(inventory) > 0:
raise ValidationError(
_(
"Cannot be more than one in progress inventory adjustment "
"affecting the same location at the same time."
)
)

@api.constrains("product_selection", "product_ids")
def _check_one_product_in_product_selection(self):
for rec in self:
Expand Down
32 changes: 29 additions & 3 deletions stock_inventory/models/stock_quant.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from odoo import _, fields, models
from odoo import _, api, fields, models


class StockQuant(models.Model):
Expand All @@ -15,7 +15,10 @@ def _apply_inventory(self):
.search([("state", "=", "in_progress")])
.filtered(
lambda x: rec.location_id in x.location_ids
or rec.location_id in x.location_ids.child_ids
or (
rec.location_id in x.location_ids.child_internal_location_ids
and not x.exclude_sublocation
)
)
)
moves = record_moves.search(
Expand All @@ -36,9 +39,32 @@ def _apply_inventory(self):
raise ValueError(_("No move lines have been created"))
move = moves[len(moves) - 1]
adjustment.stock_move_ids |= move
move.inventory_adjustment_id = adjustment
reference = move.reference
if adjustment.name and move.reference:
reference = adjustment.name + ": " + move.reference
elif adjustment.name:
reference = adjustment.name
move.write(
{
"inventory_adjustment_id": adjustment.id,
"reference": reference,
}
)
rec.to_do = False
if self.env.company.stock_inventory_auto_complete:
adjustment.action_auto_state_to_done()
return res

def _get_inventory_fields_write(self):
return super()._get_inventory_fields_write() + ["to_do"]

@api.model
def create(self, vals):
res = super().create(vals)
if self.env.context.get(
"active_model", False
) == "stock.inventory" and self.env.context.get("active_id", False):
self.env["stock.inventory"].browse(
self.env.context.get("active_id")
).refresh_stock_quant_ids()
return res
11 changes: 11 additions & 0 deletions stock_inventory/security/security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="0">
<record model="ir.rule" id="stock_inventory_comp_rule">
<field name="name">Stock Inventory multi-company</field>
<field name="model_id" ref="model_stock_inventory" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
</odoo>
1 change: 0 additions & 1 deletion stock_inventory/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down
Loading

0 comments on commit 2783864

Please sign in to comment.