[FIX] moved field potential_qty to stock_available module

This commit is contained in:
Atchuthan, Sodexis
2016-11-03 13:26:17 +05:30
parent 2e90bfadf9
commit fded3db3a4
12 changed files with 87 additions and 97 deletions

View File

@@ -16,7 +16,7 @@ class ProductProduct(models.Model):
@api.multi
@api.depends('virtual_available')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""No-op implementation of the stock available to promise.
By default, available to promise = forecasted quantity.
@@ -29,11 +29,26 @@ class ProductProduct(models.Model):
for prod in self:
prod.immediately_usable_qty = prod.virtual_available
@api.multi
@api.depends()
def _compute_potential_qty(self):
"""Set potential qty to 0.0 to define the field defintion used by
other modules to inherit it
"""
for product in self:
product.potential_qty = 0.0
immediately_usable_qty = fields.Float(
digits=dp.get_precision('Product Unit of Measure'),
compute='_immediately_usable_qty',
compute='_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")
potential_qty = fields.Float(
compute='_compute_potential_qty',
digits_compute=dp.get_precision('Product Unit of Measure'),
string='Potential',
help="Quantity of this Product that could be produced using "
"the materials already at hand.")

View File

@@ -11,7 +11,7 @@ class ProductTemplate(models.Model):
@api.multi
@api.depends('product_variant_ids.immediately_usable_qty')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""No-op implementation of the stock available to promise.
By default, available to promise = forecasted quantity.
@@ -24,11 +24,35 @@ class ProductTemplate(models.Model):
for tmpl in self:
tmpl.immediately_usable_qty = tmpl.virtual_available
@api.multi
@api.depends('product_variant_ids.potential_qty')
def _compute_potential_qty(self):
"""Compute the potential as the max of all the variants's potential.
We can't add the potential of variants: if they share components we
may not be able to make all the variants.
So we set the arbitrary rule that we can promise up to the biggest
variant's potential.
"""
for tmpl in self:
if not tmpl.product_variant_ids:
continue
tmpl.potential_qty = max(
[v.potential_qty for v in tmpl.product_variant_ids])
immediately_usable_qty = fields.Float(
digits=dp.get_precision('Product Unit of Measure'),
compute='_immediately_usable_qty',
compute='_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")
potential_qty = fields.Float(
compute='_compute_potential_qty',
digits_compute=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.")

View File

@@ -2,8 +2,7 @@
<!-- © 2014 Numérigraphe, Sodexis
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<openerp>
<data>
<odoo>
<record model="ir.ui.view" id="product_normal_form_view">
<field name="name">Quantity available to promise (variant tree)</field>
<field name="model">product.product</field>
@@ -12,7 +11,7 @@
<xpath expr="//button[@name='%(stock.action_stock_level_forecast_report_product)d']"
position="after">
<button type="action" name="%(stock.product_open_quants)d"
attrs="{'invisible':[('type', '!=', 'product')]}"
attrs="{'invisible':[('type', 'not in', ['product','consu'])]}"
class="oe_stat_button" icon="fa-building-o">
<div class="o_form_field o_stat_info">
<field name="immediately_usable_qty"
@@ -20,8 +19,16 @@
<span class="o_stat_text">Available</span>
</div>
</button>
<button type="action" name="%(stock.product_open_quants)d"
attrs="{'invisible':[('type', 'not in', ['product','consu'])]}"
class="oe_stat_button" icon="fa-building-o">
<div class="o_form_field o_stat_info">
<field name="potential_qty"
widget="statinfo" nolabel="1"/>
<span class="o_stat_text">Potential</span>
</div>
</button>
</xpath>
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -2,8 +2,7 @@
<!-- © 2014 Numérigraphe, Sodexis
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<openerp>
<data>
<odoo>
<record model="ir.ui.view" id="view_stock_available_form">
<field name="name">Quantity available to promise (form)</field>
<field name="model">product.template</field>
@@ -12,7 +11,7 @@
<xpath expr="//button[@name='%(stock.action_stock_level_forecast_report_template)d']"
position="after">
<button type="object" name="action_open_quants"
attrs="{'invisible':[('type', '!=', 'product')]}"
attrs="{'invisible':[('type', 'not in', ['product','consu'])]}"
class="oe_stat_button" icon="fa-building-o">
<div class="o_form_field o_stat_info">
<field name="immediately_usable_qty"
@@ -20,6 +19,15 @@
<span class="o_stat_text">Available</span>
</div>
</button>
<button type="action" name="%(stock.product_open_quants)d"
attrs="{'invisible':[('type', 'not in', ['product','consu'])]}"
class="oe_stat_button" icon="fa-building-o">
<div class="o_form_field o_stat_info">
<field name="potential_qty"
widget="statinfo" nolabel="1"/>
<span class="o_stat_text">Potential</span>
</div>
</button>
</xpath>
</field>
</record>
@@ -46,5 +54,4 @@
</ul>
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -2,8 +2,7 @@
<!-- © 2014 Numérigraphe, Sodexis
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<openerp>
<data>
<odoo>
<record id="view_stock_configuration" model="ir.ui.view">
<field name="name">Stock settings: quantity available to promise</field>
<field name="model">stock.config.settings</field>
@@ -35,5 +34,4 @@
</data>
</field>
</record>
</data>
</openerp>
</odoo>

View File

@@ -10,10 +10,10 @@ class ProductProduct(models.Model):
@api.multi
@api.depends('virtual_available', 'incoming_qty')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""Ignore the incoming goods in the quantity available to promise
This is the same implementation as for templates."""
super(ProductProduct, self)._immediately_usable_qty()
super(ProductProduct, self)._compute_immediately_usable_qty()
for prod in self:
prod.immediately_usable_qty -= prod.incoming_qty

View File

@@ -26,10 +26,10 @@ class ProductTemplate(models.Model):
@api.multi
@api.depends('virtual_available', 'incoming_qty')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""Ignore the incoming goods in the quantity available to promise
This is the same implementation as for variants."""
super(ProductTemplate, self)._immediately_usable_qty()
super(ProductTemplate, self)._compute_immediately_usable_qty()
for tmpl in self:
tmpl.immediately_usable_qty -= tmpl.incoming_qty

View File

@@ -5,15 +5,13 @@
'name': 'Consider the production potential is available to promise',
'version': '9.0.1.0.0',
"author": u"Numérigraphe,"
u"Sodexis,"
u"Odoo Community Association (OCA)",
'category': 'Hidden',
'depends': [
'stock_available',
'mrp'
],
'data': [
'views/product_template_view.xml',
],
'demo': [
'demo/mrp_bom.yml',
],

View File

@@ -5,7 +5,6 @@
from collections import Counter
from openerp import models, fields, api
from openerp.addons import decimal_precision as dp
from openerp.exceptions import AccessError
@@ -13,36 +12,32 @@ from openerp.exceptions import AccessError
class ProductProduct(models.Model):
_inherit = 'product.product'
potential_qty = fields.Float(
compute='_get_potential_qty',
type='float',
digits_compute=dp.get_precision('Product Unit of Measure'),
string='Potential',
help="Quantity of this Product that could be produced using "
"the materials already at hand.")
# Needed for fields dependencies
# When self.potential_qty is compute, we want to force the ORM
# to compute all the components potential_qty too.
component_ids = fields.Many2many(
comodel_name='product.product',
compute='_get_component_ids',
compute='_compute_component_ids',
)
@api.multi
@api.depends('potential_qty')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""Add the potential quantity to the quantity available to promise.
This is the same implementation as for templates."""
super(ProductProduct, self)._immediately_usable_qty()
super(ProductProduct, self)._compute_immediately_usable_qty()
for product in self:
product.immediately_usable_qty += product.potential_qty
@api.multi
@api.depends('component_ids.potential_qty')
def _get_potential_qty(self):
def _compute_potential_qty(self):
"""Compute the potential qty based on the available components."""
# call super method available in stock_available
super(ProductProduct, self)._compute_potential_qty()
bom_obj = self.env['mrp.bom']
uom_obj = self.env['product.uom']
@@ -121,7 +116,7 @@ class ProductProduct(models.Model):
return needs
def _get_component_ids(self):
def _compute_component_ids(self):
""" Compute component_ids by getting all the components for
this product.
"""

View File

@@ -2,45 +2,18 @@
# © 2014 Numérigraphe SARL
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import models, fields, api
from openerp.addons import decimal_precision as dp
from openerp import models, api
class ProductTemplate(models.Model):
_inherit = 'product.template'
potential_qty = fields.Float(
compute='_get_potential_qty',
type='float',
digits_compute=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.multi
@api.depends('potential_qty')
def _immediately_usable_qty(self):
def _compute_immediately_usable_qty(self):
"""Add the potential quantity to the quantity available to promise.
This is the same implementation as for variants."""
super(ProductTemplate, self)._immediately_usable_qty()
super(ProductTemplate, self)._compute_immediately_usable_qty()
for tmpl in self:
tmpl.immediately_usable_qty += tmpl.potential_qty
@api.multi
@api.depends('product_variant_ids.potential_qty')
def _get_potential_qty(self):
"""Compute the potential as the max of all the variants's potential.
We can't add the potential of variants: if they share components we
may not be able to make all the variants.
So we set the arbitrary rule that we can promise up to the biggest
variant's potential.
"""
for tmpl in self:
if not tmpl.product_variant_ids:
continue
tmpl.potential_qty = max(
[v.potential_qty for v in tmpl.product_variant_ids])

View File

@@ -510,7 +510,7 @@ class TestPotentialQty(TransactionCase):
self.assertEqual(5.0, p1.potential_qty)
def test_potential_qty__list(self):
# Try to highlight a bug when _get_potential_qty is called on
# Try to highlight a bug when _compute_potential_qty is called on
# a recordset with multiple products
# Recursive compute is not working

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- Add the quantity available to promise in the product form -->
<record id="view_product_form_potential_qty" model="ir.ui.view">
<field name="name">Potential quantity on product form</field>
<field name="model">product.template</field>
<field name="type">form</field>
<field name="inherit_id" ref="stock_available.view_stock_available_form" />
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='immediately_usable_qty']/ancestor::button" position="after">
<button type="action" name="%(stock.product_open_quants)d"
attrs="{'invisible':[('type', '!=', 'product')]}"
class="oe_stat_button" icon="fa-building-o">
<div class="o_form_field o_stat_info">
<field name="potential_qty"
widget="statinfo" nolabel="1"/>
<span class="o_stat_text">Potential</span>
</div>
</button>
</xpath>
</data>
</field>
</record>
</data>
</openerp>