mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_available* uses new API
This commit is contained in:
@@ -20,5 +20,3 @@
|
||||
|
||||
from . import product
|
||||
from . import res_config
|
||||
|
||||
from .product import _product_available_fnct
|
||||
|
||||
@@ -24,16 +24,6 @@
|
||||
'author': u'Numérigraphe',
|
||||
'category': 'Warehouse',
|
||||
'depends': ['stock'],
|
||||
'description': """
|
||||
Stock available to promise
|
||||
==========================
|
||||
This module proposes several options to compute the quantity available to
|
||||
promise for each product.
|
||||
This quantity is based on the projected stock and, depending on the
|
||||
configuration, it can account for various data such as sales quotations or
|
||||
immediate production capacity.
|
||||
This can be configured in the menu Settings > Configuration > Warehouse.
|
||||
""",
|
||||
'license': 'AGPL-3',
|
||||
'data': [
|
||||
'product_view.xml',
|
||||
|
||||
@@ -18,83 +18,35 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp import models, fields, api
|
||||
#from openerp.addons import decimal_precision as dp
|
||||
|
||||
|
||||
# Expose the method as a function, like when the fields are defined,
|
||||
# and use the pool to call the method from the other modules too.
|
||||
def _product_available_fnct(self, cr, uid, ids, field_names=None, arg=False,
|
||||
context=None):
|
||||
return self.pool['product.product']._product_available(
|
||||
cr, uid, ids, field_names=field_names, arg=arg, context=context)
|
||||
|
||||
|
||||
class ProductProduct(orm.Model):
|
||||
class ProductTemplate(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'
|
||||
_inherit = 'product.template'
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
"""Use _product_available_fnct to compute all the quantities."""
|
||||
# Doing this lets us change the function and not redefine fields
|
||||
super(ProductProduct, self).__init__(pool, cr)
|
||||
for coldef in self._columns.values():
|
||||
if (isinstance(coldef, fields.function)
|
||||
and coldef._multi == 'qty_available'):
|
||||
coldef._fnct = _product_available_fnct
|
||||
|
||||
def _product_available(self, cr, uid, ids, field_names=None, arg=False,
|
||||
context=None):
|
||||
@api.depends('virtual_available')
|
||||
def _product_available(self):
|
||||
"""No-op implementation of the stock available to promise.
|
||||
|
||||
By default, available to promise = forecasted quantity.
|
||||
|
||||
Must be overridden by another module that actually implement
|
||||
computations.
|
||||
The sub-modules MUST call super()._product_available BEFORE their own
|
||||
computations
|
||||
computations."""
|
||||
for product in self:
|
||||
product.immediately_usable_qty = product.virtual_available
|
||||
|
||||
Side-effect warning: This method may change the list passed as the
|
||||
field_names parameter, which will then alter the caller's state."""
|
||||
# If we didn't get a field_names list, there's nothing to do
|
||||
if field_names is None:
|
||||
return super(ProductProduct, self)._product_available(
|
||||
cr, uid, ids, field_names=field_names, arg=arg,
|
||||
context=context)
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
# Load virtual_available if it's not already asked for
|
||||
# We need it to compute immediately_usable_qty
|
||||
# We DO want to change the caller's list so we're NOT going to
|
||||
# work on a copy of field_names.
|
||||
if ('virtual_available' not in field_names
|
||||
and 'immediately_usable_qty' in field_names):
|
||||
field_names.append('virtual_available')
|
||||
|
||||
# Compute the core quantities
|
||||
res = super(ProductProduct, self)._product_available(
|
||||
cr, uid, ids, field_names=field_names, arg=arg, context=context)
|
||||
|
||||
# By default, available to promise = forecasted quantity
|
||||
if ('immediately_usable_qty' in field_names):
|
||||
for stock_qty in res.itervalues():
|
||||
stock_qty['immediately_usable_qty'] = \
|
||||
stock_qty['virtual_available']
|
||||
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'immediately_usable_qty': fields.function(
|
||||
_product_available_fnct, multi='qty_available',
|
||||
type='float',
|
||||
digits_compute=dp.get_precision('Product Unit of Measure'),
|
||||
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"),
|
||||
}
|
||||
immediately_usable_qty = fields.Float(
|
||||
compute='_product_available',
|
||||
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")
|
||||
# XXX the standard doesn't honor the UoM decimal precision. Should we?
|
||||
# digits=dp.get_precision('Product Unit of Measure'),
|
||||
|
||||
@@ -18,17 +18,15 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
from openerp import models, fields
|
||||
|
||||
|
||||
class StockConfig(orm.TransientModel):
|
||||
class StockConfig(models.TransientModel):
|
||||
"""Add options to easily install the submodules"""
|
||||
_inherit = 'stock.config.settings'
|
||||
|
||||
_columns = {
|
||||
'module_stock_available_immediately': fields.boolean(
|
||||
'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_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.")
|
||||
|
||||
@@ -26,21 +26,6 @@
|
||||
"depends": ["stock_available"],
|
||||
"author": "Camptocamp",
|
||||
"license": "AGPL-3",
|
||||
"description": u"""
|
||||
Ignore planned receptions in quantity available to promise
|
||||
----------------------------------------------------------
|
||||
|
||||
Normally the quantity available to promise is based on the virtual stock,
|
||||
which includes both planned outgoing and incoming goods.
|
||||
This module will subtract the planned receptions from the quantity available to
|
||||
promise.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
* Author: Guewen Baconnier (Camptocamp SA)
|
||||
* Sébastien BEAU (Akretion) <sebastien.beau@akretion.com>
|
||||
* Lionel Sausin (Numérigraphe) <ls@numerigraphe.com>
|
||||
""",
|
||||
"category": "Hidden",
|
||||
'installable': True
|
||||
}
|
||||
|
||||
@@ -19,41 +19,18 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm
|
||||
from openerp import models, fields, api
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
|
||||
class product_immediately_usable(orm.Model):
|
||||
"""Subtract incoming qty from immediately_usable_qty
|
||||
class ProductTemplate(models.Model):
|
||||
"""Subtract incoming qty from immediately_usable_qty"""
|
||||
_inherit = 'product.template'
|
||||
|
||||
We don't need to override the function fields, the module stock_available
|
||||
takes of it for us.
|
||||
|
||||
Side-effect warning: This method may change the list passed as the
|
||||
field_names parameter, which will then alter the caller's state."""
|
||||
_inherit = 'product.product'
|
||||
|
||||
def _product_available(self, cr, uid, ids, field_names=None,
|
||||
arg=False, context=None):
|
||||
@api.depends('virtual_available')
|
||||
def _product_available(self):
|
||||
"""Ignore the incoming goods in the quantity available to promise"""
|
||||
# If we didn't get a field_names list, there's nothing to do
|
||||
if field_names is None or 'immediately_usable_qty' not in field_names:
|
||||
return super(product_immediately_usable, self)._product_available(
|
||||
cr, uid, ids, field_names=field_names, arg=arg,
|
||||
context=context)
|
||||
super(ProductTemplate, self)._product_available()
|
||||
for product in self:
|
||||
product.immediately_usable_qty -= product.incoming_qty
|
||||
|
||||
# We need available and incoming quantities to compute
|
||||
# immediately usable quantity.
|
||||
# We DO want to change the caller's list so we're NOT going to
|
||||
# work on a copy of field_names.
|
||||
field_names.append('qty_available')
|
||||
field_names.append('incoming_qty')
|
||||
|
||||
res = super(product_immediately_usable, self)._product_available(
|
||||
cr, uid, ids, field_names=field_names, arg=arg, context=context)
|
||||
|
||||
for stock_qty in res.itervalues():
|
||||
stock_qty['immediately_usable_qty'] -= \
|
||||
stock_qty['incoming_qty']
|
||||
|
||||
return res
|
||||
immediately_usable_qty = fields.Float(compute='_product_available')
|
||||
|
||||
Reference in New Issue
Block a user