[MIGR] mrp_byproduct: new API
This commit is contained in:
committed by
Thibault Delavallée
parent
58ee9b99c3
commit
0ea69f1afc
@@ -1,14 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class mrp_bom(osv.osv):
|
||||
class MrpBom(models.Model):
|
||||
_name = 'mrp.bom'
|
||||
_description = 'Bill of Material'
|
||||
_inherit='mrp.bom'
|
||||
_inherit = 'mrp.bom'
|
||||
|
||||
_columns={
|
||||
'sub_products':fields.one2many('mrp.subproduct', 'bom_id', 'Byproducts', copy=True),
|
||||
}
|
||||
sub_products = fields.One2many('mrp.subproduct', 'bom_id', 'Byproducts', copy=True)
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class mrp_production(osv.osv):
|
||||
class Production(models.Model):
|
||||
_description = 'Production'
|
||||
_inherit= 'mrp.production'
|
||||
_inherit = 'mrp.production'
|
||||
|
||||
|
||||
def action_confirm(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def action_confirm(self):
|
||||
""" Confirms production order and calculates quantity based on subproduct_type.
|
||||
@return: Newly generated picking Id.
|
||||
"""
|
||||
move_obj = self.pool.get('stock.move')
|
||||
picking_id = super(mrp_production,self).action_confirm(cr, uid, ids, context=context)
|
||||
product_uom_obj = self.pool.get('product.uom')
|
||||
for production in self.browse(cr, uid, ids):
|
||||
source = production.product_id.property_stock_production.id
|
||||
Move = self.env['stock.move']
|
||||
picking_id = super(Production, self).action_confirm()
|
||||
UoM = self.env['product.uom']
|
||||
for production in self:
|
||||
if not production.bom_id:
|
||||
continue
|
||||
source = production.product_id.property_stock_production.id
|
||||
for sub_product in production.bom_id.sub_products:
|
||||
product_uom_factor = product_uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, production.bom_id.product_uom.id)
|
||||
product_uom_factor = UoM._compute_qty_obj(production.product_uom, production.product_qty, production.bom_id.product_uom)
|
||||
qty1 = sub_product.product_qty
|
||||
if sub_product.subproduct_type == 'variable':
|
||||
if production.product_qty:
|
||||
qty1 *= product_uom_factor / (production.bom_id.product_qty or 1.0)
|
||||
if sub_product.subproduct_type == 'variable' and production.product_qty:
|
||||
qty1 *= product_uom_factor / (production.bom_id.product_qty or 1.0)
|
||||
data = {
|
||||
'name': 'PROD:'+production.name,
|
||||
'name': 'PROD:%s' % production.name,
|
||||
'date': production.date_planned,
|
||||
'product_id': sub_product.product_id.id,
|
||||
'product_uom_qty': qty1,
|
||||
@@ -39,12 +38,12 @@ class mrp_production(osv.osv):
|
||||
'origin': production.name,
|
||||
'subproduct_id': sub_product.id
|
||||
}
|
||||
move_id = move_obj.create(cr, uid, data, context=context)
|
||||
move_obj.action_confirm(cr, uid, [move_id], context=context)
|
||||
|
||||
move = Move.create(data)
|
||||
move.action_confirm()
|
||||
return picking_id
|
||||
|
||||
def _get_subproduct_factor(self, cr, uid, move, context=None):
|
||||
@api.model
|
||||
def _get_subproduct_factor(self, move):
|
||||
"""Compute the factor to compute the quantity of products to produce. By default,
|
||||
it's always equal to the quantity encoded in the production order or the production wizard, but with
|
||||
the module mrp_byproduct installed it can differ for byproducts having type 'variable'.
|
||||
@@ -56,16 +55,17 @@ class mrp_production(osv.osv):
|
||||
if subproduct_record.bom_id.product_qty:
|
||||
subproduct_factor = subproduct_record.product_qty / subproduct_record.bom_id.product_qty
|
||||
return subproduct_factor
|
||||
return super(mrp_production, self)._get_subproduct_factor(cr, uid, move, context=context)
|
||||
return super(Production, self)._get_subproduct_factor(move)
|
||||
|
||||
def _calculate_produce_line_qty(self, cr, uid, move, quantity, context=None):
|
||||
@api.model
|
||||
def _calculate_produce_line_qty(self, move, quantity):
|
||||
""" Compute the quantity and remainig quantity of products to produce.
|
||||
:param move: stock.move record that needs to be produced, identify the product to produce.
|
||||
:param quantity: quantity to produce, in the uom of the production order.
|
||||
:return: The quantity and remaining quantity of product produce.
|
||||
"""
|
||||
if move.subproduct_id.subproduct_type == 'variable':
|
||||
subproduct_factor = self._get_subproduct_factor(cr, uid, move, context=context)
|
||||
subproduct_factor = self._get_subproduct_factor(move)
|
||||
# Needed when producing more than maximum quantity
|
||||
qty = min(subproduct_factor * quantity, move.product_qty)
|
||||
remaining_qty = subproduct_factor * quantity - qty
|
||||
@@ -73,4 +73,4 @@ class mrp_production(osv.osv):
|
||||
elif move.subproduct_id.subproduct_type == 'fixed':
|
||||
return move.product_qty, 0
|
||||
# no subproduct
|
||||
return super(mrp_production, self)._calculate_produce_line_qty(cr, uid, move, quantity, context=context)
|
||||
return super(Production, self)._calculate_produce_line_qty(move, quantity)
|
||||
|
||||
@@ -1,47 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import fields
|
||||
from openerp.osv import osv
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.tools.translate import _
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
class mrp_subproduct(osv.osv):
|
||||
|
||||
class MrpSubProduct(models.Model):
|
||||
_name = 'mrp.subproduct'
|
||||
_description = 'Byproduct'
|
||||
_columns={
|
||||
'product_id': fields.many2one('product.product', 'Product', required=True),
|
||||
'product_qty': fields.float('Product Qty', digits_compute=dp.get_precision('Product Unit of Measure'), required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
|
||||
'subproduct_type': fields.selection([('fixed','Fixed'),('variable','Variable')], 'Quantity Type', required=True, help="Define how the quantity of byproducts will be set on the production orders using this BoM.\
|
||||
'Fixed' depicts a situation where the quantity of created byproduct is always equal to the quantity set on the BoM, regardless of how many are created in the production order.\
|
||||
By opposition, 'Variable' means that the quantity will be computed as\
|
||||
'(quantity of byproduct set on the BoM / quantity of manufactured product set on the BoM * quantity of manufactured product in the production order.)'"),
|
||||
'bom_id': fields.many2one('mrp.bom', 'BoM', ondelete='cascade'),
|
||||
}
|
||||
_defaults={
|
||||
'subproduct_type': 'variable',
|
||||
'product_qty': lambda *a: 1.0,
|
||||
}
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, product_id, context=None):
|
||||
""" Changes UoM if product_id changes.
|
||||
@param product_id: Changed product_id
|
||||
@return: Dictionary of changed values
|
||||
"""
|
||||
if product_id:
|
||||
prod = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
|
||||
v = {'product_uom': prod.uom_id.id}
|
||||
return {'value': v}
|
||||
return {}
|
||||
product_id = fields.Many2one('product.product', 'Product', required=True)
|
||||
product_qty = fields.Float(
|
||||
'Product Qty',
|
||||
default=1.0, digits_compute=dp.get_precision('Product Unit of Measure'), required=True)
|
||||
product_uom = fields.Many2one('product.uom', 'Product Unit of Measure', required=True)
|
||||
subproduct_type = fields.Selection([
|
||||
('fixed', 'Fixed'),
|
||||
('variable', 'Variable')], string='Quantity Type',
|
||||
default='variable', required=True,
|
||||
help="Define how the quantity of byproducts will be set on the production orders using this BoM.\n"
|
||||
"'Fixed' depicts a situation where the quantity of created byproduct is always equal to the "
|
||||
" quantity set on the BoM, regardless of how many are created in the production order.\n"
|
||||
"By opposition, 'Variable' means that the quantity will be computed as (quantity of byproduct "
|
||||
"set on the BoM / quantity of manufactured product set on the BoM * quantity of manufactured "
|
||||
"product in the production order.)")
|
||||
bom_id = fields.Many2one('mrp.bom', 'BoM', ondelete='cascade')
|
||||
|
||||
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})
|
||||
@api.onchange('product_id')
|
||||
def onchange_product_id(self):
|
||||
""" Changes UoM if product_id changes. """
|
||||
if self.product_id:
|
||||
self.product_uom = self.product_id.uom_id.id
|
||||
|
||||
@api.onchange('product_uom')
|
||||
def onchange_uom(self):
|
||||
res = {}
|
||||
if self.product_uom and self.product_id and self.product_uom.category_id != self.product_id.uom_id.category_id:
|
||||
res['warning'] = {
|
||||
'title': _('Warning'),
|
||||
'message': _('The Product Unit of Measure you chose has a different category than in the product form.')
|
||||
}
|
||||
self.product_uom = self.product_id.uom_id.id
|
||||
return res
|
||||
|
||||
@@ -7,5 +7,6 @@ from openerp import fields, models
|
||||
class Stok_Move(models.Model):
|
||||
_inherit = 'stock.move'
|
||||
|
||||
subproduct_id = fields.Many2one('mrp.subproduct', 'Subproduct',
|
||||
subproduct_id = fields.Many2one(
|
||||
'mrp.subproduct', 'Subproduct',
|
||||
help="Subproduct line that generated the move in a manufacturing order")
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
<page string="Byproducts">
|
||||
<field name="sub_products">
|
||||
<tree string="Byproducts" editable="top">
|
||||
<field name="product_id" on_change="onchange_product_id(product_id)"/>
|
||||
<field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom" groups="product.group_uom"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="subproduct_type"/>
|
||||
</tree>
|
||||
<form string="Byproducts">
|
||||
<field name="product_id" on_change="onchange_product_id(product_id)"/>
|
||||
<field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom" groups="product.group_uom"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="subproduct_type"/>
|
||||
</form>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp.osv import osv
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class change_production_qty(osv.osv_memory):
|
||||
class change_production_qty(models.TransientModel):
|
||||
_inherit = 'change.production.qty'
|
||||
|
||||
def _update_product_to_produce(self, cr, uid, prod, qty, context=None):
|
||||
move_lines_obj = self.pool.get('stock.move')
|
||||
prod_obj = self.pool.get('mrp.production')
|
||||
for m in prod.move_created_ids:
|
||||
if m.product_id.id == prod.product_id.id:
|
||||
move_lines_obj.write(cr, uid, [m.id], {'product_uom_qty': qty})
|
||||
@api.model
|
||||
def _update_product_to_produce(self, prod, qty):
|
||||
Production = self.env['mrp.production']
|
||||
for move in prod.move_created_ids:
|
||||
if move.product_id == prod.product_id:
|
||||
move.write({'product_uom_qty': qty})
|
||||
else:
|
||||
for sub_product_line in prod.bom_id.sub_products:
|
||||
if sub_product_line.product_id.id == m.product_id.id:
|
||||
factor = prod_obj._get_subproduct_factor(cr, uid, m, context=context)
|
||||
if sub_product_line.product_id == move.product_id:
|
||||
factor = Production._get_subproduct_factor(move)
|
||||
subproduct_qty = sub_product_line.subproduct_type == 'variable' and qty * factor or sub_product_line.product_qty
|
||||
move_lines_obj.write(cr, uid, [m.id], {'product_uom_qty': subproduct_qty})
|
||||
move.write({'product_uom_qty': subproduct_qty})
|
||||
|
||||
Reference in New Issue
Block a user