[FIX] mrp: solve bom structures views
authorSimon Lejeune <sle@openerp.com>
Fri, 26 Sep 2014 14:12:02 +0000 (16:12 +0200)
committerJosse Colpaert <jco@odoo.com>
Tue, 30 Sep 2014 08:31:33 +0000 (10:31 +0200)
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

addons/mrp/mrp.py
addons/mrp/mrp_view.xml
addons/mrp/report/bom_structure.py
addons/mrp/views/report_mrpbomstructure.xml

index 7fe6b81..f302ff8 100644 (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):
index 564e1f7..c43df1f 100644 (file)
 
        <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"/>
         <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>
index c8a3132..800b616 100644 (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
index fe34edf..f636076 100644 (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>
                     <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>
-                            </tr>
-                            <tr t-foreach="get_children(o.bom_line_ids)" t-as="l">
                                 <td>
-                                    <span style="color: white;" t-esc="'... '*(l['level'])"/>
+                                    <span t-field="o.code"/>
                                 </td>
-                                 <td>
-                                        [ <span t-esc="l['pcode']"/> ]
-                                        <span t-esc="l['pname']"/>
+                            </tr>
+                            <tr t-foreach="get_children(o.bom_line_ids)" t-as="l">
+                                <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'])"/>