[FIX] mrp: solve bom structures views

A previous refactoring brought a bom_line_ids field on the mrp.bom, thus
deprecating the _child_compute method. But the previous refactoring did
not go through all the views, breaking everything that relied on the
_child_compute (tree view, report). As the bom_line_ids refers to the
mrp.bom.line model (introduced by this previous refactoring, note:
_child_compute returned mrp.bom record) and that we can't make a treeview
showing different model, this patch introduce a function field _get_child_bom_lines
on the mrp.line model, allowing to go through the bom_line_ids of a mrp.bom.line
if this mrp.bom.line refers to a mrp.bom.

[IMP] Rename bom_line_ids to child_line_ids in mrp_bom_line to avoid confusion
This commit is contained in:
Simon Lejeune 2014-09-26 16:12:02 +02:00 committed by Josse Colpaert
parent 25d2ed6d4b
commit 68c8d90221
4 changed files with 35 additions and 62 deletions

View File

@ -155,42 +155,6 @@ class mrp_bom(osv.osv):
_description = 'Bill of Material'
_inherit = ['mail.thread']
def _child_compute(self, cr, uid, ids, name, arg, context=None):
""" Gets child bom.
@param self: The object pointer
@param cr: The current row, from the database cursor,
@param uid: The current user ID for security checks
@param ids: List of selected IDs
@param name: Name of the field
@param arg: User defined argument
@param context: A standard dictionary for contextual values
@return: Dictionary of values
"""
result = {}
if context is None:
context = {}
bom_obj = self.pool.get('mrp.bom')
bom_id = context and context.get('active_id', False) or False
cr.execute('select id from mrp_bom')
if all(bom_id != r[0] for r in cr.fetchall()):
ids.sort()
bom_id = ids[0]
bom_parent = bom_obj.browse(cr, uid, bom_id, context=context)
for bom in self.browse(cr, uid, ids, context=context):
if (bom_parent) or (bom.id == bom_id):
result[bom.id] = map(lambda x: x.id, bom.bom_line_ids)
else:
result[bom.id] = []
if bom.bom_line_ids:
continue
ok = ((name=='child_complete_ids'))
if (bom.type=='phantom' or ok):
sids = bom_obj.search(cr, uid, [('product_tmpl_id','=',bom.product_tmpl_id.id)])
if sids:
bom2 = bom_obj.browse(cr, uid, sids[0], context=context)
result[bom.id] += map(lambda x: x.id, bom2.bom_line_ids)
return result
_columns = {
'name': fields.char('Name'),
'code': fields.char('Reference', size=16),
@ -213,7 +177,6 @@ class mrp_bom(osv.osv):
'product_rounding': fields.float('Product Rounding', help="Rounding applied on the product quantity."),
'product_efficiency': fields.float('Manufacturing Efficiency', required=True, help="A factor of 0.9 means a loss of 10% during the production process."),
'property_ids': fields.many2many('mrp.property', string='Properties'),
'child_complete_ids': fields.function(_child_compute, relation='mrp.bom', string="BoM Hierarchy", type='many2many'),
'company_id': fields.many2one('res.company', 'Company', required=True),
}
@ -387,6 +350,21 @@ class mrp_bom_line(osv.osv):
_name = 'mrp.bom.line'
_order = "sequence"
def _get_child_bom_lines(self, cr, uid, ids, field_name, arg, context=None):
"""If the BOM line refers to a BOM, return the ids of the child BOM lines"""
bom_obj = self.pool['mrp.bom']
res = {}
for bom_line in self.browse(cr, uid, ids, context=context):
bom_id = bom_obj._bom_find(cr, uid,
product_tmpl_id=bom_line.product_id.product_tmpl_id.id,
product_id=bom_line.product_id.id, context=context)
if bom_id:
child_bom = bom_obj.browse(cr, uid, bom_id, context=context)
res[bom_line.id] = [x.id for x in child_bom.bom_line_ids]
else:
res[bom_line.id] = False
return res
_columns = {
'type': fields.selection([('normal', 'Normal'), ('phantom', 'Phantom')], 'BoM Line Type', required=True,
help="Phantom: this product line will not appear in the raw materials of manufacturing orders,"
@ -409,6 +387,7 @@ class mrp_bom_line(osv.osv):
'bom_id': fields.many2one('mrp.bom', 'Parent BoM', ondelete='cascade', select=True, required=True),
'attribute_value_ids': fields.many2many('product.attribute.value', string='Variants', help="BOM Product Variants needed form apply this line."),
'child_line_ids': fields.function(_get_child_bom_lines, relation="mrp.bom.line", string="BOM lines of the referred bom", type="one2many")
}
def _get_uom_id(self, cr, uid, *args):

View File

@ -436,16 +436,13 @@
<record id="mrp_bom_tree_view" model="ir.ui.view">
<field name="name">mrp.bom.tree</field>
<field name="model">mrp.bom</field>
<!--field name="field_parent">child_complete_ids</field-->
<field name="model">mrp.bom.line</field>
<field name="field_parent">child_line_ids</field>
<field name="arch" type="xml">
<tree string="Bill of Materials">
<field name="sequence" invisible="1"/>
<field name="name" invisible="1"/>
<field name="product_tmpl_id"/>
<field name="product_id"/>
<field name="product_uom" groups="product.group_uom"/>
<field name="code"/>
<field name="type"/>
<field name="routing_id" groups="mrp.group_mrp_routings"/>
<field name="date_start"/>
@ -592,8 +589,8 @@
<record id="action2" model="ir.actions.act_window">
<field name="name">Bill of Materials Structure</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.bom</field>
<field name="domain">[('id', 'in', active_ids)]</field>
<field name="res_model">mrp.bom.line</field>
<field name="domain">[('bom_id', 'in', active_ids)]</field>
<field name="view_type">tree</field>
<field name="view_id" ref="mrp_bom_tree_view"/>
<field name="view_type">tree</field>

View File

@ -19,7 +19,6 @@
#
##############################################################################
import time
from openerp.osv import osv
from openerp.report import report_sxw
@ -28,8 +27,7 @@ class bom_structure(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(bom_structure, self).__init__(cr, uid, name, context=context)
self.localcontext.update({
'time': time,
'get_children':self.get_children,
'get_children': self.get_children,
})
def get_children(self, object, level=0):
@ -38,18 +36,17 @@ class bom_structure(report_sxw.rml_parse):
def _get_rec(object, level):
for l in object:
res = {}
res['name'] = l.name
res['pname'] = l.product_id.name
res['pcode'] = l.product_id.default_code
res['pqty'] = l.product_qty
res['uname'] = l.product_uom.name
res['code'] = l.code
res['level'] = level
res['code'] = l.bom_id.code
result.append(res)
if l.child_complete_ids:
if l.child_line_ids:
if level<6:
level += 1
_get_rec(l.child_complete_ids,level)
_get_rec(l.child_line_ids,level)
if level>0 and level<6:
level -= 1
return result

View File

@ -6,12 +6,10 @@
<t t-call="report.internal_layout">
<div class="page">
<h2>BOM Structure</h2>
<table class="table table-condensed">
<thead>
<tr>
<th>BOM Name</th>
<th>Product Name</th>
<th>Quantity</th>
<th>BOM Ref</th>
</tr>
@ -19,21 +17,23 @@
<tbody>
<t t-foreach="docs" t-as="o">
<tr style="font-weight: bold;">
<td><span t-field="o.name"/></td>
<td><span t-field="o.product_id.default_code"/><span t-field="o.product_id.name"/></td>
<td>
<span t-field="o.product_id.default_code"/>
<span t-field="o.name"/>
</td>
<td>
<span t-field="o.product_qty"/>
<span groups="product.group_uom" t-field="o.product_uom.name"/>
</td>
<td><span t-field="o.code"/></td>
<td>
<span t-field="o.code"/>
</td>
</tr>
<tr t-foreach="get_children(o.bom_line_ids)" t-as="l">
<td>
<span style="color: white;" t-esc="'... '*(l['level'])"/>
</td>
<td>
[ <span t-esc="l['pcode']"/> ]
<span t-esc="l['pname']"/>
<td style="padding-left: 20px;">
<span style="color: white;" t-esc="'... '*(l['level'])"/>[
<span t-esc="l['pcode']"/>]
<span t-esc="l['pname']"/>
</td>
<td>
<span t-esc="formatLang(l['pqty'])"/>