añadido stock_available de OCA/stock-logistics-workflow por dependencia de website_stock_available

This commit is contained in:
santiky 2021-09-14 14:27:00 +02:00
parent c14ed5b4ef
commit 9bd253a931
Signed by: snt
GPG key ID: A9FD34930EADBE71
45 changed files with 5494 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# Copyright 2014 Camptocamp, Akretion, Numérigraphe
# Copyright 2016 Sodexis
# Copyright 2019 Sergio Díaz <sergiodm.1989@gmail.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import product_product
from . import product_template
from . import res_config_settings

View file

@ -0,0 +1,76 @@
# Copyright 2014 Numérigraphe
# Copyright 2016 Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo.addons import decimal_precision as dp
from odoo.addons.stock.models.product import OPERATORS
class ProductProduct(models.Model):
""" Add a field for the stock available to promise.
Useful implementations need to be installed through the Settings menu or by
installing one of the modules stock_available_*
"""
_inherit = 'product.product'
@api.multi
def _compute_available_quantities_dict(self):
stock_dict = self._compute_quantities_dict(
self._context.get('lot_id'),
self._context.get('owner_id'),
self._context.get('package_id'),
self._context.get('from_date'),
self._context.get('to_date'))
res = {}
for product in self:
res[product.id] = {
'immediately_usable_qty': stock_dict[product.id][
'virtual_available'],
'potential_qty': 0.0
}
return res, stock_dict
@api.multi
@api.depends('virtual_available')
def _compute_available_quantities(self):
res, _ = self._compute_available_quantities_dict()
for product in self:
for key, value in res[product.id].items():
if hasattr(product, key):
product[key] = value
immediately_usable_qty = fields.Float(
digits=dp.get_precision('Product Unit of Measure'),
compute='_compute_available_quantities',
search="_search_immediately_usable_qty",
string='Available to promise',
help="Stock for this Product that can be safely proposed "
"for sale to Customers.\n"
"The definition of this value can be configured to suit "
"your needs.")
potential_qty = fields.Float(
compute='_compute_available_quantities',
digits=dp.get_precision('Product Unit of Measure'),
string='Potential',
help="Quantity of this Product that could be produced using "
"the materials already at hand.")
@api.model
def _search_immediately_usable_qty(self, operator, value):
""" Search function for the immediately_usable_qty field.
The search is quite similar to the Odoo search about quantity available
(addons/stock/models/product.py,253; _search_product_quantity function)
:param operator: str
:param value: str
:return: list of tuple (domain)
"""
products = self.search([])
# Force prefetch
products.mapped("immediately_usable_qty")
product_ids = []
for product in products:
if OPERATORS[operator](product.immediately_usable_qty, value):
product_ids.append(product.id)
return [('id', 'in', product_ids)]

View file

@ -0,0 +1,77 @@
# Copyright 2014 Numérigraphe
# Copyright 2016 Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from odoo.addons import decimal_precision as dp
from odoo.addons.stock.models.product import OPERATORS
class ProductTemplate(models.Model):
_inherit = 'product.template'
@api.multi
@api.depends('product_variant_ids.immediately_usable_qty',
'product_variant_ids.potential_qty')
def _compute_available_quantities(self):
res = self._compute_available_quantities_dict()
for product in self:
for key, value in res[product.id].items():
if key in product._fields:
product[key] = value
@api.multi
def _compute_available_quantities_dict(self):
variants_dict, _ = self.mapped(
'product_variant_ids')._compute_available_quantities_dict()
res = {}
for template in self:
immediately_usable_qty = sum(
[variants_dict[p.id]["immediately_usable_qty"] -
variants_dict[p.id]["potential_qty"] for p in
template.product_variant_ids])
potential_qty = max(
[variants_dict[p.id]["potential_qty"] for p in
template.product_variant_ids] or [0.0])
res[template.id] = {
"immediately_usable_qty": immediately_usable_qty +
potential_qty,
"potential_qty": potential_qty,
}
return res
immediately_usable_qty = fields.Float(
digits=dp.get_precision('Product Unit of Measure'),
compute='_compute_available_quantities',
search="_search_immediately_usable_qty",
string='Available to promise',
help="Stock for this Product that can be safely proposed "
"for sale to Customers.\n"
"The definition of this value can be configured to suit "
"your needs")
potential_qty = fields.Float(
compute='_compute_available_quantities',
digits=dp.get_precision('Product Unit of Measure'),
string='Potential',
help="Quantity of this Product that could be produced using "
"the materials already at hand. "
"If the product has several variants, this will be the biggest "
"quantity that can be made for a any single variant.")
@api.model
def _search_immediately_usable_qty(self, operator, value):
""" Search function for the immediately_usable_qty field.
The search is quite similar to the Odoo search about quantity available
(addons/stock/models/product.py,253; _search_product_quantity function)
:param operator: str
:param value: str
:return: list of tuple (domain)
"""
products = self.search([])
# Force prefetch
products.mapped("immediately_usable_qty")
product_ids = []
for product in products:
if OPERATORS[operator](product.immediately_usable_qty, value):
product_ids.append(product.id)
return [('id', 'in', product_ids)]

View file

@ -0,0 +1,69 @@
# Copyright 2014 Numérigraphe
# Copyright 2016 Sodexis
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
class ResConfigSettings(models.TransientModel):
"""Add options to easily install the submodules"""
_inherit = 'res.config.settings'
@api.model
def _get_stock_available_mrp_based_on(self):
"""Gets the available languages for the selection."""
pdct_fields = self.env['ir.model.fields'].search(
[('model', '=', 'product.product'),
('ttype', '=', 'float')])
return [
(field.name, field.field_description)
for field in sorted(pdct_fields, key=lambda f: f.field_description)
]
module_stock_available_immediately = fields.Boolean(
string='Exclude incoming goods',
help="This will subtract incoming quantities from the quantities "
"available to promise.\n"
"This installs the module stock_available_immediately.")
module_stock_available_sale = fields.Boolean(
string='Exclude goods already in sale quotations',
help="This will subtract quantities from the sale quotations from "
"the quantities available to promise.\n"
"This installs the modules stock_available_sale.\n"
"If the modules sale and sale_delivery_date are not "
"installed, this will install them too")
module_stock_available_mrp = fields.Boolean(
string='Include the production potential',
help="This will add the quantities of goods that can be "
"immediately manufactured, to the quantities available to "
"promise.\n"
"This installs the module stock_available_mrp.\n"
"If the module mrp is not installed, this will install it "
"too")
stock_available_mrp_based_on = fields.Selection(
_get_stock_available_mrp_based_on,
string='based on',
help="Choose the field of the product which will be used to compute "
"potential.\nIf empty, Quantity On Hand is used.\n"
"Only the quantity fields have meaning for computing stock",
)
@api.model
def get_values(self):
res = super(ResConfigSettings, self).get_values()
res.update(stock_available_mrp_based_on=self.env[
'ir.config_parameter'].sudo().get_param(
'stock_available_mrp_based_on',
'qty_available')
)
return res
@api.multi
def set_values(self):
super(ResConfigSettings, self).set_values()
self.env['ir.config_parameter'].sudo().set_param(
'stock_available_mrp_based_on', self.stock_available_mrp_based_on)