[11.0] mrp_multi_level:

* fix api.depends fields fro main supplier.
 * fix ordering and missing demo file in manifest.
 * Update README.
 * fix action_view* methods.
 * readd hook to exclude in mrp initialization
 * fix computation of qty available (it was considering several times sub-locations).
 * Remove contraint for outoing and incoming moves to be moved in/outside the company, they can be internal transfers.
 * mrp.moves visible with technical settings.
 * Show product and allow to search by it in mrp.inventory.
This commit is contained in:
Lois Rilo
2018-11-20 10:10:32 +01:00
committed by joan
parent 0ba8be007f
commit e6e1af8da9
14 changed files with 184 additions and 99 deletions

View File

@@ -50,20 +50,29 @@ Key Features
Configuration
=============
* Go to *Manufacturing > MRP > MRP Area* and define or edit any existing area.
You can specify the working hours for every area.
MRP Areas
~~~~~~~~~
* Go to *Manufacturing > Configuration > MRP Areas* and define or edit
any existing area. You can specify the working hours for every area.
Product MRP Area Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Go to *Manufacturing > Master Data > Product MRP Area Parameters* and set
the MRP parameters for a given product and area.
Usage
=====
To manually run the MRP scheduler:
#. Go to *Manufacturing > MRP > Run MRP Multi Level*.
#. Go to *Manufacturing > Operations > Run MRP Multi Level*.
#. On the wizard click *Run MRP*.
To launch replenishment orders (moves, purchases, production orders...):
#. Go to *Manufacturing > MRP > MRP Inventory*.
#. Go to *Manufacturing > Operations > MRP Inventory*.
#. Filter with *To procure*.
#. Select multiple records and click on *Action > Procure* or click the right
hand side gears in any record.
@@ -78,6 +87,17 @@ Known issues / Roadmap
Changelog
=========
11.0.2.0.0 (2018-11-20)
~~~~~~~~~~~~~~~~~~~~~~~
* [REW] Refactor MRP Area.
(`#322 <https://github.com/OCA/manufacture/pull/322>`_):
* MRP product concept dropped in favor of *Product MRP Area Parameters*.
This allow to set different MRP parameters for the same product in
different areas.
* Menu items reordering.
11.0.1.1.0 (2018-08-30)
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -38,9 +38,9 @@
'demo': [
'demo/product_category_demo.xml',
'demo/product_product_demo.xml',
'demo/product_product_demo.xml',
'demo/product_mrp_area_demo.xml',
'demo/res_partner_demo.xml',
'demo/product_supplierinfo_demo.xml',
'demo/product_mrp_area_demo.xml',
'demo/mrp_bom_demo.xml',
'demo/initial_on_hand_demo.xml',
],

View File

@@ -17,7 +17,6 @@ class MrpInventory(models.Model):
# TODO: name to pass to procurements?
# TODO: compute procurement_date to pass to the wizard? not needed for
# PO at least. Check for MO and moves
# TODO: substract qty already procured.
# TODO: show a LT based on the procure method?
mrp_area_id = fields.Many2one(
@@ -25,9 +24,14 @@ class MrpInventory(models.Model):
related='product_mrp_area_id.mrp_area_id', store=True,
)
product_mrp_area_id = fields.Many2one(
comodel_name='product.mrp.area', string='Product',
comodel_name='product.mrp.area', string='Product Parameters',
index=True,
)
product_id = fields.Many2one(
comodel_name='product.product',
related='product_mrp_area_id.product_id',
store=True,
)
uom_id = fields.Many2one(
comodel_name='product.uom', string='Product UoM',
compute='_compute_uom_id',

View File

@@ -11,19 +11,21 @@ class ProductMRPArea(models.Model):
_description = 'Product MRP Area'
active = fields.Boolean(default=True)
mrp_area_id = fields.Many2one('mrp.area',
required=True,
)
product_id = fields.Many2one('product.product',
required=True,
string='Product',
)
product_tmpl_id = fields.Many2one('product.template',
readonly=True,
related='product_id.product_tmpl_id',
store=True,
)
mrp_area_id = fields.Many2one(
comodel_name='mrp.area',
required=True,
)
product_id = fields.Many2one(
comodel_name='product.product',
required=True,
string='Product',
)
product_tmpl_id = fields.Many2one(
comodel_name='product.template',
readonly=True,
related='product_id.product_tmpl_id',
store=True,
)
# TODO: applicable and exclude... redundant??
mrp_applicable = fields.Boolean(string='MRP Applicable')
mrp_exclude = fields.Boolean(string='Exclude from MRP')
@@ -71,10 +73,11 @@ class ProductMRPArea(models.Model):
qty_available = fields.Float('Quantity Available',
compute='_compute_qty_available')
mrp_move_ids = fields.One2many(comodel_name='mrp.move',
inverse_name='product_mrp_area_id',
readonly=True,
)
mrp_move_ids = fields.One2many(
comodel_name='mrp.move',
inverse_name='product_mrp_area_id',
readonly=True,
)
_sql_constraints = [
('product_mrp_area_uniq', 'unique(product_id, mrp_area_id)',
'The product/MRP Area parameters combination must be unique.'),
@@ -89,17 +92,9 @@ class ProductMRPArea(models.Model):
@api.multi
def _compute_qty_available(self):
for rec in self:
qty_available = 0.0
product_obj = self.env['product.product']
# TODO: move mrp_qty_available computation, maybe unreserved??
location_ids = self.env['stock.location'].search(
[('id', 'child_of',
rec.mrp_area_id.location_id.id)])
for location in location_ids:
product_l = product_obj.with_context(
{'location': location.id}).browse(rec.product_id.id)
qty_available += product_l.qty_available
rec.qty_available = qty_available
rec.qty_available = rec.product_id.with_context(
{'location': rec.mrp_area_id.location_id.id}).qty_available
@api.multi
def _compute_supply_method(self):
@@ -115,7 +110,8 @@ class ProductMRPArea(models.Model):
rec.supply_method = rule.action if rule else 'none'
@api.multi
@api.depends('supply_method')
@api.depends('supply_method', 'product_id.route_ids',
'product_id.seller_ids')
def _compute_main_supplier(self):
"""Simplified and similar to procurement.rule logic."""
for rec in self.filtered(lambda r: r.supply_method == 'buy'):

View File

@@ -28,7 +28,8 @@ class Product(models.Model):
mrp_area_count = fields.Integer(
string='MRP Area Parameter Count',
readonly=True,
compute='_compute_mrp_area_count')
compute='_compute_mrp_area_count',
)
@api.multi
def _compute_mrp_area_count(self):
@@ -40,12 +41,11 @@ class Product(models.Model):
self.ensure_one()
action = self.env.ref('mrp_multi_level.product_mrp_area_action')
result = action.read()[0]
product_ids = self.ids
if len(product_ids) > 1:
result['domain'] = [('product_id', 'in', product_ids)]
area_ids = self.mrp_area_ids.ids
if self.mrp_area_count != 1:
result['domain'] = [('id', 'in', area_ids)]
else:
res = self.env.ref('mrp_multi_level.product_mrp_area_form', False)
result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = product_ids[0]
result['context'] = {'default_product_id': product_ids[0]}
result['res_id'] = area_ids[0]
return result

View File

@@ -15,7 +15,8 @@ class ProductTemplate(models.Model):
mrp_area_count = fields.Integer(
string='MRP Area Parameter Count',
readonly=True,
compute='_compute_mrp_area_count')
compute='_compute_mrp_area_count',
)
@api.multi
def _compute_mrp_area_count(self):
@@ -29,12 +30,10 @@ class ProductTemplate(models.Model):
result = action.read()[0]
mrp_area_ids = self.with_context(
active_test=False).mrp_area_ids.ids
if len(mrp_area_ids) > 1:
if len(mrp_area_ids) != 1:
result['domain'] = [('id', 'in', mrp_area_ids)]
else:
res = self.env.ref('mrp_multi_level.product_mrp_area_form', False)
result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = mrp_area_ids[0]
result['context'] = {
'default_product_id': self.product_variant_ids[0].id}
return result

View File

@@ -1,2 +1,11 @@
* Go to *Manufacturing > MRP > MRP Area* and define or edit any existing area.
You can specify the working hours for every area.
MRP Areas
~~~~~~~~~
* Go to *Manufacturing > Configuration > MRP Areas* and define or edit
any existing area. You can specify the working hours for every area.
Product MRP Area Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Go to *Manufacturing > Master Data > Product MRP Area Parameters* and set
the MRP parameters for a given product and area.

View File

@@ -1,3 +1,14 @@
11.0.2.0.0 (2018-11-20)
~~~~~~~~~~~~~~~~~~~~~~~
* [REW] Refactor MRP Area.
(`#322 <https://github.com/OCA/manufacture/pull/322>`_):
* MRP product concept dropped in favor of *Product MRP Area Parameters*.
This allow to set different MRP parameters for the same product in
different areas.
* Menu items reordering.
11.0.1.1.0 (2018-08-30)
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -1,11 +1,11 @@
To manually run the MRP scheduler:
#. Go to *Manufacturing > MRP > Run MRP Multi Level*.
#. Go to *Manufacturing > Operations > Run MRP Multi Level*.
#. On the wizard click *Run MRP*.
To launch replenishment orders (moves, purchases, production orders...):
#. Go to *Manufacturing > MRP > MRP Inventory*.
#. Go to *Manufacturing > Operations > MRP Inventory*.
#. Filter with *To procure*.
#. Select multiple records and click on *Action > Procure* or click the right
hand side gears in any record.

View File

@@ -386,41 +386,56 @@ and explodes this down to the lowest level.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="id6">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id7">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id8">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#changelog" id="id9">Changelog</a><ul>
<li><a class="reference internal" href="#id1" id="id10">11.0.1.1.0 (2018-08-30)</a></li>
<li><a class="reference internal" href="#id3" id="id11">11.0.1.0.1 (2018-08-03)</a></li>
<li><a class="reference internal" href="#id5" id="id12">11.0.1.0.0 (2018-07-09)</a></li>
<li><a class="reference internal" href="#configuration" id="id8">Configuration</a><ul>
<li><a class="reference internal" href="#mrp-areas" id="id9">MRP Areas</a></li>
<li><a class="reference internal" href="#product-mrp-area-parameters" id="id10">Product MRP Area Parameters</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="id13">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id14">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id15">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id16">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id17">Maintainers</a></li>
<li><a class="reference internal" href="#usage" id="id11">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id12">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#changelog" id="id13">Changelog</a><ul>
<li><a class="reference internal" href="#id1" id="id14">11.0.2.0.0 (2018-11-20)</a></li>
<li><a class="reference internal" href="#id3" id="id15">11.0.1.1.0 (2018-08-30)</a></li>
<li><a class="reference internal" href="#id5" id="id16">11.0.1.0.1 (2018-08-03)</a></li>
<li><a class="reference internal" href="#id7" id="id17">11.0.1.0.0 (2018-07-09)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="id18">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id19">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id20">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id21">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id22">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#id6">Configuration</a></h2>
<h2><a class="toc-backref" href="#id8">Configuration</a></h2>
<div class="section" id="mrp-areas">
<h3><a class="toc-backref" href="#id9">MRP Areas</a></h3>
<ul class="simple">
<li>Go to <em>Manufacturing &gt; MRP &gt; MRP Area</em> and define or edit any existing area.
You can specify the working hours for every area.</li>
<li>Go to <em>Manufacturing &gt; Configuration &gt; MRP Areas</em> and define or edit
any existing area. You can specify the working hours for every area.</li>
</ul>
</div>
<div class="section" id="product-mrp-area-parameters">
<h3><a class="toc-backref" href="#id10">Product MRP Area Parameters</a></h3>
<ul class="simple">
<li>Go to <em>Manufacturing &gt; Master Data &gt; Product MRP Area Parameters</em> and set
the MRP parameters for a given product and area.</li>
</ul>
</div>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#id7">Usage</a></h2>
<h2><a class="toc-backref" href="#id11">Usage</a></h2>
<p>To manually run the MRP scheduler:</p>
<ol class="arabic simple">
<li>Go to <em>Manufacturing &gt; MRP &gt; Run MRP Multi Level</em>.</li>
<li>Go to <em>Manufacturing &gt; Operations &gt; Run MRP Multi Level</em>.</li>
<li>On the wizard click <em>Run MRP</em>.</li>
</ol>
<p>To launch replenishment orders (moves, purchases, production orders…):</p>
<ol class="arabic simple">
<li>Go to <em>Manufacturing &gt; MRP &gt; MRP Inventory</em>.</li>
<li>Go to <em>Manufacturing &gt; Operations &gt; MRP Inventory</em>.</li>
<li>Filter with <em>To procure</em>.</li>
<li>Select multiple records and click on <em>Action &gt; Procure</em> or click the right
hand side gears in any record.</li>
@@ -428,23 +443,36 @@ hand side gears in any record.</li>
</ol>
</div>
<div class="section" id="known-issues-roadmap">
<h2><a class="toc-backref" href="#id8">Known issues / Roadmap</a></h2>
<h2><a class="toc-backref" href="#id12">Known issues / Roadmap</a></h2>
<ul class="simple">
<li>The functionality related to field <em>Nbr. Days</em> in products is not
functional for the time being. Please, stay tuned to future updates.</li>
</ul>
</div>
<div class="section" id="changelog">
<h2><a class="toc-backref" href="#id9">Changelog</a></h2>
<h2><a class="toc-backref" href="#id13">Changelog</a></h2>
<div class="section" id="id1">
<h3><a class="toc-backref" href="#id10">11.0.1.1.0 (2018-08-30)</a></h3>
<h3><a class="toc-backref" href="#id14">11.0.2.0.0 (2018-11-20)</a></h3>
<ul class="simple">
<li>[REW] Refactor MRP Area.
(<a class="reference external" href="https://github.com/OCA/manufacture/pull/322">#322</a>):<ul>
<li>MRP product concept dropped in favor of <em>Product MRP Area Parameters</em>.
This allow to set different MRP parameters for the same product in
different areas.</li>
<li>Menu items reordering.</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="id3">
<h3><a class="toc-backref" href="#id15">11.0.1.1.0 (2018-08-30)</a></h3>
<ul class="simple">
<li>[FIX] Consider <em>Qty Multiple</em> on product to propose the quantity to procure.
(<a class="reference external" href="https://github.com/OCA/manufacture/pull/297">#297</a>)</li>
</ul>
</div>
<div class="section" id="id3">
<h3><a class="toc-backref" href="#id11">11.0.1.0.1 (2018-08-03)</a></h3>
<div class="section" id="id5">
<h3><a class="toc-backref" href="#id16">11.0.1.0.1 (2018-08-03)</a></h3>
<ul class="simple">
<li>[FIX] User and system locales doesnt break MRP calculation.
(<a class="reference external" href="https://github.com/OCA/manufacture/pull/290">#290</a>)</li>
@@ -453,15 +481,15 @@ as a related on MRP Areas.
(<a class="reference external" href="https://github.com/OCA/manufacture/pull/290">#290</a>)</li>
</ul>
</div>
<div class="section" id="id5">
<h3><a class="toc-backref" href="#id12">11.0.1.0.0 (2018-07-09)</a></h3>
<div class="section" id="id7">
<h3><a class="toc-backref" href="#id17">11.0.1.0.0 (2018-07-09)</a></h3>
<ul class="simple">
<li>Start of the history.</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#id13">Bug Tracker</a></h2>
<h2><a class="toc-backref" href="#id18">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/manufacture/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
@@ -469,16 +497,16 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#id14">Credits</a></h2>
<h2><a class="toc-backref" href="#id19">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#id15">Authors</a></h3>
<h3><a class="toc-backref" href="#id20">Authors</a></h3>
<ul class="simple">
<li>Ucamco</li>
<li>Eficent</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#id16">Contributors</a></h3>
<h3><a class="toc-backref" href="#id21">Contributors</a></h3>
<ul class="simple">
<li>Wim Audenaert &lt;<a class="reference external" href="mailto:wim.audenaert&#64;ucamco.com">wim.audenaert&#64;ucamco.com</a>&gt;</li>
<li>Jordi Ballester &lt;<a class="reference external" href="mailto:jordi.ballester&#64;eficent.com">jordi.ballester&#64;eficent.com</a>&gt;</li>
@@ -486,7 +514,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#id17">Maintainers</a></h3>
<h3><a class="toc-backref" href="#id22">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@@ -23,7 +23,7 @@ class TestMrpMultiLevel(SavepointCase):
cls.estimate_obj = cls.env['stock.demand.estimate']
cls.mrp_multi_level_wiz = cls.env['mrp.multi.level']
cls.mrp_inventory_procure_wiz = cls.env['mrp.inventory.procure']
cls.mrp_inventory_obj = cls.env['mrp.inventory']
cls.mrp_inventory_obj = cls.env['mrp.inventory']
cls.mrp_move_obj = cls.env['mrp.move']
cls.fp_1 = cls.env.ref('mrp_multi_level.product_product_fp_1')
@@ -417,9 +417,9 @@ class TestMrpMultiLevel(SavepointCase):
expected = [200.0, 290.0, 90.0, 0.0, 72.0, 0.0]
self.assertEqual(moves.mapped('running_availability'), expected)
# Actions counters for PP-1:
product_mrp_area = self.product_mrp_area_obj.search([
('product_id', '=', self.pp_1.id)
])
# product_mrp_area = self.product_mrp_area_obj.search([
# ('product_id', '=', self.pp_1.id)
# ]) # TODO
# self.assertEqual(product_mrp_area.nbr_mrp_actions, 3) # TODO
# self.assertEqual(product_mrp_area.nbr_mrp_actions_4w, 3) # TODO

View File

@@ -11,6 +11,7 @@
<group>
<group>
<field name="mrp_area_id"/>
<field name="product_id"/>
<field name="product_mrp_area_id"/>
<field name="date"/>
</group>
@@ -35,7 +36,7 @@
<field name="arch" type="xml">
<tree string="MRP Inventory" create="false">
<field name="mrp_area_id"/>
<field name="product_mrp_area_id"/>
<field name="product_id"/>
<field name="date"/>
<field name="uom_id" groups="product.group_uom"/>
<field name="initial_on_hand_qty"/>
@@ -84,7 +85,7 @@
<field name="arch" type="xml">
<search string="MRP Inventory">
<group name="select" expand="0" string="Selection...">
<field name="product_mrp_area_id"/>
<field name="product_id"/>
<field name="mrp_area_id"/>
</group>
<separator/>

View File

@@ -59,6 +59,28 @@
<field name="main_supplierinfo_id"/>
</group>
</group>
<group string="MRP moves" name="mrp_moves" groups="base.group_no_one">
<field name="mrp_move_ids" nolabel="1">
<tree>
<field name="mrp_action_date"/>
<field name="mrp_date"/>
<field name="current_date"/>
<field name="mrp_origin"/>
<field name="state"/>
<field name="mrp_order_number"/>
<field name="parent_product_id"/>
<field name="name"/>
<field name="mrp_qty"/>
<field name="current_qty"/>
<field name="running_availability"/>
<field name="mrp_minimum_stock" />
<field name="mrp_action"/>
<field name="mrp_type"/>
<field name="mrp_move_up_ids"/>
<field name="mrp_processed"/>
</tree>
</field>
</group>
</sheet>
</form>
</field>
@@ -70,10 +92,8 @@
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Product MRP Area parameters">
<group expand="0" string="Selection...">
<field name="product_id" select='1'/>
<field name="mrp_area_id"/>
</group>
<field name="product_id"/>
<field name="mrp_area_id"/>
<separator/>
</search>
</field>

View File

@@ -70,12 +70,6 @@ class MultiLevelMrp(models.TransientModel):
@api.model
def _prepare_mrp_move_data_from_stock_move(
self, product_mrp_area, move, direction='in'):
if not((move.location_id.usage == 'internal' and
move.location_dest_id.usage != 'internal')
or (move.location_id.usage != 'internal' and
move.location_dest_id.usage == 'internal')):
# TODO: not sure about this 'if'...
return {}
if direction == 'out':
mrp_type = 'd'
product_qty = -move.product_qty
@@ -416,7 +410,8 @@ class MultiLevelMrp(models.TransientModel):
return True
@api.model
def _prepare_mrp_move_data_from_purchase_order(self, poline, product_mrp_area):
def _prepare_mrp_move_data_from_purchase_order(
self, poline, product_mrp_area):
mrp_date = date.today()
if fields.Date.from_string(poline.date_planned) > date.today():
mrp_date = fields.Date.from_string(poline.date_planned)
@@ -497,7 +492,8 @@ class MultiLevelMrp(models.TransientModel):
for mrp_area in mrp_areas:
for product_mrp_area in product_mrp_areas.filtered(
lambda a: a.mrp_area_id == mrp_area):
if product_mrp_area.mrp_exclude:
if self._exclude_from_mrp(
product_mrp_area.product_id, mrp_area):
continue
init_counter += 1
log_msg = 'MRP INIT: %s - %s ' % (
@@ -615,7 +611,8 @@ class MultiLevelMrp(models.TransientModel):
if onhand < product_mrp_area.mrp_minimum_stock and \
nbr_create == 0:
qtytoorder = product_mrp_area.mrp_minimum_stock - onhand
qtytoorder = \
product_mrp_area.mrp_minimum_stock - onhand
cm = self.create_move(
product_mrp_area_id=product_mrp_area,
mrp_date=date.today(),