[MERGE] forward port of branch saas-3 up to 7ab4137
authorDenis Ledoux <dle@odoo.com>
Fri, 14 Nov 2014 15:58:24 +0000 (16:58 +0100)
committerDenis Ledoux <dle@odoo.com>
Fri, 14 Nov 2014 15:58:24 +0000 (16:58 +0100)
1  2 
addons/account/account.py
addons/hr/static/src/xml/suggestions.xml
addons/mail/static/src/xml/suggestions.xml
addons/mrp/mrp.py
addons/point_of_sale/security/point_of_sale_security.xml
addons/product/product.py
addons/web/static/src/js/search.js
addons/web/static/src/js/view_form.js

Simple merge
@@@ -320,120 -372,24 +320,125 @@@ class mrp_bom(osv.osv)
          if default is None:
              default = {}
          bom_data = self.read(cr, uid, id, [], context=context)
 -        default.update(name=_("%s (copy)") % (bom_data['name']), bom_id=False)
 +        default.update(name=_("%s (copy)") % (bom_data['name']))
          return super(mrp_bom, self).copy_data(cr, uid, id, default, context=context)
  
 +    def onchange_uom(self, cr, uid, ids, product_tmpl_id, product_uom, context=None):
 +        res = {'value': {}}
 +        if not product_uom or not product_tmpl_id:
 +            return res
 +        product = self.pool.get('product.template').browse(cr, uid, product_tmpl_id, context=context)
 +        uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
 +        if uom.category_id.id != product.uom_id.category_id.id:
 +            res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
 +            res['value'].update({'product_uom': product.uom_id.id})
 +        return res
 +
+     def unlink(self, cr, uid, ids, context=None):
 -        if self.pool['mrp.production'].search(cr, uid, [
 -                ('bom_id', 'in', ids), ('state', 'not in', ['done', 'cancel'])
 -            ], context=context):
++        if self.pool['mrp.production'].search(cr, uid, [('bom_id', 'in', ids), ('state', 'not in', ['done', 'cancel'])], context=context):
+             raise osv.except_osv(_('Warning!'), _('You can not delete a Bill of Material with running manufacturing orders.\nPlease close or cancel it first.'))
+         return super(mrp_bom, self).unlink(cr, uid, ids, context=context)
 +    def onchange_product_tmpl_id(self, cr, uid, ids, product_tmpl_id, product_qty=0, context=None):
 +        """ Changes UoM and name if product_id changes.
 +        @param product_id: Changed product_id
 +        @return:  Dictionary of changed values
 +        """
 +        res = {}
 +        if product_tmpl_id:
 +            prod = self.pool.get('product.template').browse(cr, uid, product_tmpl_id, context=context)
 +            res['value'] = {
 +                'name': prod.name,
 +                'product_uom': prod.uom_id.id,
 +            }
 +        return res
 +
 +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,"
 +                     "it will be directly replaced by the raw materials of its own BoM, without triggering"
 +                     "an extra manufacturing order."),
 +        'product_id': fields.many2one('product.product', 'Product', required=True),
 +        'product_uos_qty': fields.float('Product UOS Qty'),
 +        'product_uos': fields.many2one('product.uom', 'Product UOS', help="Product UOS (Unit of Sale) is the unit of measurement for the invoicing and promotion of stock."),
 +        'product_qty': fields.float('Product Quantity', required=True, digits_compute=dp.get_precision('Product Unit of Measure')),
 +        'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True,
 +            help="Unit of Measure (Unit of Measure) is the unit of measurement for the inventory control"),
 +        
 +        'date_start': fields.date('Valid From', help="Validity of component. Keep empty if it's always valid."),
 +        'date_stop': fields.date('Valid Until', help="Validity of component. Keep empty if it's always valid."),
 +        'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying."),
 +        'routing_id': fields.many2one('mrp.routing', 'Routing', help="The list of operations (list of work centers) to produce the finished product. The routing is mainly used to compute work center costs during operations and to plan future loads on work centers based on production planning."),
 +        '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% within the production process."),
 +        'property_ids': fields.many2many('mrp.property', string='Properties'), #Not used
 +
 +        '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):
 +        return self.pool["product.uom"].search(cr, uid, [], limit=1, order='id')[0]
 +    _defaults = {
 +        'product_qty': lambda *a: 1.0,
 +        'product_efficiency': lambda *a: 1.0,
 +        'product_rounding': lambda *a: 0.0,
 +        'type': lambda *a: 'normal',
 +        'product_uom': _get_uom_id,
 +    }
 +    _sql_constraints = [
 +        ('bom_qty_zero', 'CHECK (product_qty>0)', 'All product quantities must be greater than 0.\n' \
 +            'You should install the mrp_byproduct module if you want to manage extra products on BoMs !'),
 +    ]
 +
 +    def onchange_uom(self, cr, uid, ids, product_id, product_uom, context=None):
 +        res = {'value': {}}
 +        if not product_uom or not product_id:
 +            return res
 +        product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
 +        uom = self.pool.get('product.uom').browse(cr, uid, product_uom, context=context)
 +        if uom.category_id.id != product.uom_id.category_id.id:
 +            res['warning'] = {'title': _('Warning'), 'message': _('The Product Unit of Measure you chose has a different category than in the product form.')}
 +            res['value'].update({'product_uom': product.uom_id.id})
 +        return res
  
 -def rounding(f, r):
 -    # TODO for trunk: log deprecation warning
 -    # _logger.warning("Deprecated rounding method, please use tools.float_round to round floats.")
 -    import math
 -    if not r:
 -        return f
 -    return math.ceil(f / r) * r
 +    def onchange_product_id(self, cr, uid, ids, product_id, product_qty=0, context=None):
 +        """ Changes UoM if product_id changes.
 +        @param product_id: Changed product_id
 +        @return:  Dictionary of changed values
 +        """
 +        res = {}
 +        if product_id:
 +            prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
 +            res['value'] = {
 +                'product_uom': prod.uom_id.id,
 +                'product_uos_qty': 0,
 +                'product_uos': False
 +            }
 +            if prod.uos_id.id:
 +                res['value']['product_uos_qty'] = product_qty * prod.uos_coeff
 +                res['value']['product_uos'] = prod.uos_id.id
 +        return res
  
  class mrp_production(osv.osv):
      """
          <field name="name">Point Of Sale Config</field>
          <field name="model_id" ref="model_pos_config" />
          <field name="global" eval="True" />
 -        <field name="domain_force">[('warehouse_id.company_id','child_of',[user.company_id.id])]</field>
 +        <field name="domain_force">[('company_id','child_of',[user.company_id.id])]</field>
      </record>
+     <record id="rule_pos_order_report_multi_company" model="ir.rule">
+         <field name="name">Point Of Sale Order Analysis multi-company</field>
+         <field name="model_id" ref="model_report_pos_order"/>
+         <field name="global" eval="True"/>
+         <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
+     </record>
  </data>
  </openerp>
Simple merge
Simple merge
Simple merge