[IMP] stock_available* uses new API

This commit is contained in:
Lionel Sausin
2015-02-27 16:39:03 +01:00
parent cb186fe179
commit 8504307c7b
6 changed files with 37 additions and 137 deletions

View File

@@ -20,5 +20,3 @@
from . import product
from . import res_config
from .product import _product_available_fnct

View File

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

View File

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

View File

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

View File

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

View File

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