mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
Standard migration. Also some copyrights are removed because they were added by mistake in the fist place (copy+paste issues ;) )
116 lines
4.3 KiB
Python
116 lines
4.3 KiB
Python
# Copyright 2018 Camptocamp SA
|
|
# Copyright 2016-19 ForgeFlow S.L. (https://www.forgeflow.com)
|
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
from odoo.tools.float_utils import float_round
|
|
|
|
from odoo.addons.stock.models.product import OPERATORS
|
|
|
|
|
|
class ProductTemplate(models.Model):
|
|
_inherit = "product.template"
|
|
|
|
qty_available_not_res = fields.Float(
|
|
string="Quantity On Hand Unreserved",
|
|
digits="Product Unit of Measure",
|
|
compute="_compute_product_available_not_res",
|
|
search="_search_quantity_unreserved",
|
|
)
|
|
|
|
@api.depends("product_variant_ids.qty_available_not_res")
|
|
def _compute_product_available_not_res(self):
|
|
for tmpl in self:
|
|
if isinstance(tmpl.id, models.NewId):
|
|
continue
|
|
tmpl.qty_available_not_res = sum(
|
|
tmpl.mapped("product_variant_ids.qty_available_not_res")
|
|
)
|
|
|
|
def action_open_quants_unreserved(self):
|
|
products_ids = self.mapped("product_variant_ids").ids
|
|
quants = self.env["stock.quant"].search([("product_id", "in", products_ids)])
|
|
quant_ids = quants.filtered(
|
|
lambda x: x.product_id.qty_available_not_res > 0
|
|
).ids
|
|
result = self.env.ref("stock.product_template_open_quants").read()[0]
|
|
result["domain"] = [("id", "in", quant_ids)]
|
|
result["context"] = {
|
|
"search_default_locationgroup": 1,
|
|
"search_default_internal_loc": 1,
|
|
}
|
|
return result
|
|
|
|
def _search_quantity_unreserved(self, operator, value):
|
|
domain = [("qty_available_not_res", operator, value)]
|
|
product_variant_ids = self.env["product.product"].search(domain)
|
|
return [("product_variant_ids", "in", product_variant_ids.ids)]
|
|
|
|
|
|
class ProductProduct(models.Model):
|
|
_inherit = "product.product"
|
|
|
|
qty_available_not_res = fields.Float(
|
|
string="Qty Available Not Reserved",
|
|
digits="Product Unit of Measure",
|
|
compute="_compute_qty_available_not_reserved",
|
|
search="_search_quantity_unreserved",
|
|
)
|
|
|
|
def _prepare_domain_available_not_reserved(self):
|
|
domain_quant = [("product_id", "in", self.ids)]
|
|
domain_quant_locations = self._get_domain_locations()[0]
|
|
domain_quant.extend(domain_quant_locations)
|
|
return domain_quant
|
|
|
|
def _compute_product_available_not_res_dict(self):
|
|
|
|
res = {}
|
|
|
|
domain_quant = self._prepare_domain_available_not_reserved()
|
|
quants = (
|
|
self.env["stock.quant"]
|
|
.with_context(lang=False)
|
|
.read_group(
|
|
domain_quant,
|
|
["product_id", "location_id", "quantity", "reserved_quantity"],
|
|
["product_id", "location_id"],
|
|
lazy=False,
|
|
)
|
|
)
|
|
product_sums = {}
|
|
for quant in quants:
|
|
# create a dictionary with the total value per products
|
|
product_sums.setdefault(quant["product_id"][0], 0.0)
|
|
product_sums[quant["product_id"][0]] += (
|
|
quant["quantity"] - quant["reserved_quantity"]
|
|
)
|
|
for product in self.with_context(prefetch_fields=False, lang=""):
|
|
available_not_res = float_round(
|
|
product_sums.get(product.id, 0.0),
|
|
precision_rounding=product.uom_id.rounding,
|
|
)
|
|
res[product.id] = {"qty_available_not_res": available_not_res}
|
|
return res
|
|
|
|
@api.depends("stock_move_ids.product_qty", "stock_move_ids.state")
|
|
def _compute_qty_available_not_reserved(self):
|
|
res = self._compute_product_available_not_res_dict()
|
|
for prod in self:
|
|
qty = res[prod.id]["qty_available_not_res"]
|
|
prod.qty_available_not_res = qty
|
|
return res
|
|
|
|
def _search_quantity_unreserved(self, operator, value):
|
|
if operator not in OPERATORS:
|
|
raise UserError(_("Invalid domain operator %s") % operator)
|
|
if not isinstance(value, (float, int)):
|
|
raise UserError(_("Invalid domain right operand %s") % value)
|
|
|
|
ids = []
|
|
for product in self.search([]):
|
|
if OPERATORS[operator](product.qty_available_not_res, value):
|
|
ids.append(product.id)
|
|
return [("id", "in", ids)]
|