diff --git a/stock_available/__init__.py b/stock_available/__init__.py index 6dff1269a..036bf665c 100644 --- a/stock_available/__init__.py +++ b/stock_available/__init__.py @@ -18,5 +18,4 @@ # ############################################################################## -from . import product -from . import res_config +from . import models diff --git a/stock_available/__openerp__.py b/stock_available/__openerp__.py index 0f2042a78..cbcd39b70 100644 --- a/stock_available/__openerp__.py +++ b/stock_available/__openerp__.py @@ -26,7 +26,8 @@ 'depends': ['stock'], 'license': 'AGPL-3', 'data': [ - 'product_view.xml', - 'res_config_view.xml', + 'views/product_template_view.xml', + 'views/product_product_view.xml', + 'views/res_config_view.xml', ] } diff --git a/stock_available/models/__init__.py b/stock_available/models/__init__.py new file mode 100644 index 000000000..bf26a289f --- /dev/null +++ b/stock_available/models/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import product_template +from . import product_product +from . import res_config diff --git a/stock_available/product.py b/stock_available/models/product_product.py similarity index 54% rename from stock_available/product.py rename to stock_available/models/product_product.py index 199a8ef63..c529040b7 100644 --- a/stock_available/product.py +++ b/stock_available/models/product_product.py @@ -22,45 +22,29 @@ from openerp import models, fields, api from openerp.addons import decimal_precision as dp -class ProductTemplate(models.Model): +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.template' + _inherit = 'product.product' - # immediately usable quantity caluculated with the quant method - @api.multi + @api.one @api.depends('virtual_available') def _immediately_usable_qty(self): - stock_location_obj = self.env['stock.location'] - internal_locations = stock_location_obj.search([ - ('usage', '=', 'internal')]) - sublocations = self.env['stock.location'] - for location in internal_locations: - sublocations += stock_location_obj.search( - [('id', 'child_of', location.id)]) - for product_template in self: - products = self.env['product.product'].search([ - ('product_tmpl_id', '=', product_template.id)]) - quant_obj = self.env['stock.quant'] - quants = quant_obj.search([ - ('location_id', 'in', sublocations.ids), - ('product_id', 'in', products.ids), - ('reservation_id', '=', False)]) - availability = 0 - if quants: - for quant in quants: - availability += quant.qty - product_template.immediately_usable_qty = availability + """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.""" + self.immediately_usable_qty = self.virtual_available immediately_usable_qty = fields.Float( digits=dp.get_precision('Product Unit of Measure'), compute='_immediately_usable_qty', - string='Available to promise (quant calculation)', + 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 , this number is obtained by using the new odoo 8 " - "quants, so it gives us the actual current quants minus reserved" - "quants") + "your needs") diff --git a/stock_available/models/product_template.py b/stock_available/models/product_template.py new file mode 100644 index 000000000..fe55ecc47 --- /dev/null +++ b/stock_available/models/product_template.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# This module is copyright (C) 2014 Numérigraphe SARL. All Rights Reserved. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, fields, api +from openerp.addons import decimal_precision as dp + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + @api.one + @api.depends('virtual_available') + def _immediately_usable_qty(self): + """Compute the quantity using all the variants""" + self.immediately_usable_qty = sum( + [v.immediately_usable_qty for v in self.product_variant_ids]) + + immediately_usable_qty = fields.Float( + digits=dp.get_precision('Product Unit of Measure'), + compute='_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") diff --git a/stock_available/res_config.py b/stock_available/models/res_config.py similarity index 100% rename from stock_available/res_config.py rename to stock_available/models/res_config.py diff --git a/stock_available/views/product_product_view.xml b/stock_available/views/product_product_view.xml new file mode 100644 index 000000000..22dd36b2e --- /dev/null +++ b/stock_available/views/product_product_view.xml @@ -0,0 +1,20 @@ + + + + + Quantity available to promise (variant tree) + product.product + + + + + red:immediately_usable_qty<0;blue:immediately_usable_qty>=0 and state in ('draft', 'end', 'obsolete');black:immediately_usable_qty>=0 and state not in ('draft', 'end', 'obsolete') + + + + + + + + + diff --git a/stock_available/product_view.xml b/stock_available/views/product_template_view.xml similarity index 100% rename from stock_available/product_view.xml rename to stock_available/views/product_template_view.xml diff --git a/stock_available/res_config_view.xml b/stock_available/views/res_config_view.xml similarity index 100% rename from stock_available/res_config_view.xml rename to stock_available/views/res_config_view.xml diff --git a/stock_available_immediately/__init__.py b/stock_available_immediately/__init__.py old mode 100755 new mode 100644 index 867607b7d..4c76a5131 --- a/stock_available_immediately/__init__.py +++ b/stock_available_immediately/__init__.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # Author Guewen Baconnier. Copyright Camptocamp SA @@ -17,3 +17,5 @@ # along with this program. If not, see . # ############################################################################## + +from . import models diff --git a/stock_available_immediately/models/__init__.py b/stock_available_immediately/models/__init__.py new file mode 100644 index 000000000..a28883030 --- /dev/null +++ b/stock_available_immediately/models/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author Guewen Baconnier. Copyright Camptocamp SA +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import product_product diff --git a/stock_available_immediately/models/product_product.py b/stock_available_immediately/models/product_product.py new file mode 100644 index 000000000..d3050f872 --- /dev/null +++ b/stock_available_immediately/models/product_product.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright 2010-2012 Camptocamp SA +# Copyright (C) 2011 Akretion Sébastien BEAU +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp import models, api + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + @api.one + def _immediately_usable_qty(self): + """Ignore the incoming goods in the quantity available to promise""" + super(ProductProduct, self)._immediately_usable_qty() + self.immediately_usable_qty -= self.incoming_qty diff --git a/stock_available_immediately/tests/__init__.py b/stock_available_immediately/tests/__init__.py new file mode 100644 index 000000000..8185fdf1f --- /dev/null +++ b/stock_available_immediately/tests/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import test_stock_available_immediately diff --git a/stock_available/tests/test_stock_available.py b/stock_available_immediately/tests/test_stock_available_immediately.py similarity index 98% rename from stock_available/tests/test_stock_available.py rename to stock_available_immediately/tests/test_stock_available_immediately.py index 2c46f6460..be9f43006 100644 --- a/stock_available/tests/test_stock_available.py +++ b/stock_available_immediately/tests/test_stock_available_immediately.py @@ -20,7 +20,7 @@ from openerp.tests.common import TransactionCase -class testStockLogisticsWarehouse(TransactionCase): +class TestStockLogisticsWarehouse(TransactionCase): def test01_stock_levels(self): """checking that immediately_usable_qty actually reflects \