From: Denis Ledoux Date: Fri, 14 Nov 2014 15:58:24 +0000 (+0100) Subject: [MERGE] forward port of branch saas-3 up to 7ab4137 X-Git-Url: http://git.inspyration.org/?a=commitdiff_plain;h=d9e48bae42f84d0880ac1be66c31c50be08d9417;p=odoo%2Fodoo.git [MERGE] forward port of branch saas-3 up to 7ab4137 --- d9e48bae42f84d0880ac1be66c31c50be08d9417 diff --cc addons/mrp/mrp.py index 2f8d399,e9e099b..5a257f2 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@@ -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): """ diff --cc addons/point_of_sale/security/point_of_sale_security.xml index 58096a0,41b3fbb..1a47206 --- a/addons/point_of_sale/security/point_of_sale_security.xml +++ b/addons/point_of_sale/security/point_of_sale_security.xml @@@ -23,7 -23,13 +23,13 @@@ Point Of Sale Config - [('warehouse_id.company_id','child_of',[user.company_id.id])] + [('company_id','child_of',[user.company_id.id])] + + Point Of Sale Order Analysis multi-company + + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] +