2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2008-10-10 13:36:46 +00:00
##############################################################################
2010-12-15 09:46:44 +00:00
#
2009-10-14 11:15:34 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2008-10-10 13:36:46 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
2008-10-10 13:36:46 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2008-10-10 13:36:46 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-12-15 09:46:44 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-10 13:36:46 +00:00
#
##############################################################################
2012-12-06 14:56:32 +00:00
from openerp . osv import fields
from openerp . osv import osv
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2012-12-06 14:56:32 +00:00
from openerp . tools . translate import _
2008-10-10 13:36:46 +00:00
class mrp_subproduct ( osv . osv ) :
_name = ' mrp.subproduct '
2012-05-04 10:45:06 +00:00
_description = ' Byproduct '
2008-10-10 13:36:46 +00:00
_columns = {
2009-03-15 16:51:44 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , required = True ) ,
2012-04-25 08:54:15 +00:00
' 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 ) ,
2012-10-08 10:28:36 +00:00
' 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 . \
2011-11-09 15:10:38 +00:00
By opposition , ' Variable ' means that the quantity will be computed as \
2012-10-08 10:28:36 +00:00
' (quantity of byproduct set on the BoM / quantity of manufactured product set on the BoM * quantity of manufactured product in the production order.) ' " ),
2009-03-15 16:51:44 +00:00
' bom_id ' : fields . many2one ( ' mrp.bom ' , ' BoM ' ) ,
}
_defaults = {
2011-11-09 15:10:38 +00:00
' subproduct_type ' : ' variable ' ,
2012-11-26 12:00:42 +00:00
' product_qty ' : lambda * a : 1.0 ,
2009-03-15 16:51:44 +00:00
}
2010-12-15 09:46:44 +00:00
2010-11-19 13:48:01 +00:00
def onchange_product_id ( self , cr , uid , ids , product_id , context = None ) :
2010-05-25 12:36:48 +00:00
""" Changes UoM if product_id changes.
@param product_id : Changed product_id
@return : Dictionary of changed values
"""
2009-03-15 16:51:44 +00:00
if product_id :
2010-11-19 13:48:01 +00:00
prod = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product_id , context = context )
2010-05-25 12:36:48 +00:00
v = { ' product_uom ' : prod . uom_id . id }
2008-10-10 13:36:46 +00:00
return { ' value ' : v }
2009-03-15 16:51:44 +00:00
return { }
2008-10-10 13:36:46 +00:00
2012-10-03 11:13:35 +00:00
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 :
2012-10-15 05:19:41 +00:00
res [ ' warning ' ] = { ' title ' : _ ( ' Warning ' ) , ' message ' : _ ( ' The Product Unit of Measure you chose has a different category than in the product form. ' ) }
2012-10-03 11:13:35 +00:00
res [ ' value ' ] . update ( { ' product_uom ' : product . uom_id . id } )
return res
2008-10-10 13:36:46 +00:00
mrp_subproduct ( )
class mrp_bom ( osv . osv ) :
_name = ' mrp.bom '
_description = ' Bill of Material '
_inherit = ' mrp.bom '
2010-12-15 09:46:44 +00:00
2008-10-10 13:36:46 +00:00
_columns = {
2012-10-08 10:28:36 +00:00
' sub_products ' : fields . one2many ( ' mrp.subproduct ' , ' bom_id ' , ' Byproducts ' ) ,
2009-03-15 16:51:44 +00:00
}
2012-02-14 15:57:46 +00:00
2008-10-10 13:36:46 +00:00
mrp_bom ( )
class mrp_production ( osv . osv ) :
_description = ' Production '
2010-12-15 09:46:44 +00:00
_inherit = ' mrp.production '
2008-10-10 13:36:46 +00:00
2012-02-14 15:57:46 +00:00
2008-10-10 13:36:46 +00:00
def action_confirm ( self , cr , uid , ids ) :
2010-05-25 12:36:48 +00:00
""" Confirms production order and calculates quantity based on subproduct_type.
@return : Newly generated picking Id .
"""
picking_id = super ( mrp_production , self ) . action_confirm ( cr , uid , ids )
2012-11-23 11:43:39 +00:00
product_uom_obj = self . pool . get ( ' product.uom ' )
2010-05-11 05:35:06 +00:00
for production in self . browse ( cr , uid , ids ) :
2012-07-27 01:52:02 +00:00
source = production . product_id . property_stock_production . id
2010-05-11 05:35:06 +00:00
if not production . bom_id :
continue
for sub_product in production . bom_id . sub_products :
2012-11-23 11:43:39 +00:00
product_uom_factor = product_uom_obj . _compute_qty ( cr , uid , production . product_uom . id , production . product_qty , production . bom_id . product_uom . id )
2010-05-11 05:35:06 +00:00
qty1 = sub_product . product_qty
qty2 = production . product_uos and production . product_uos_qty or False
2012-11-23 11:43:39 +00:00
product_uos_factor = 0.0
if qty2 and production . bom_id . product_uos . id :
product_uos_factor = product_uom_obj . _compute_qty ( cr , uid , production . product_uos . id , production . product_uos_qty , production . bom_id . product_uos . id )
2010-05-25 12:36:48 +00:00
if sub_product . subproduct_type == ' variable ' :
2009-03-15 16:51:44 +00:00
if production . product_qty :
2012-11-23 11:43:39 +00:00
qty1 * = product_uom_factor / ( production . bom_id . product_qty or 1.0 )
2009-03-15 16:51:44 +00:00
if production . product_uos_qty :
2012-11-23 11:43:39 +00:00
qty2 * = product_uos_factor / ( production . bom_id . product_uos_qty or 1.0 )
2010-05-11 05:35:06 +00:00
data = {
2010-05-25 12:36:48 +00:00
' name ' : ' PROD: ' + production . name ,
2010-09-21 13:14:39 +00:00
' date ' : production . date_planned ,
2008-10-10 13:36:46 +00:00
' product_id ' : sub_product . product_id . id ,
2009-03-15 16:51:44 +00:00
' product_qty ' : qty1 ,
2008-10-10 13:36:46 +00:00
' product_uom ' : sub_product . product_uom . id ,
2009-03-15 16:51:44 +00:00
' product_uos_qty ' : qty2 ,
2008-10-10 13:36:46 +00:00
' product_uos ' : production . product_uos and production . product_uos . id or False ,
' location_id ' : source ,
' location_dest_id ' : production . location_dest_id . id ,
' move_dest_id ' : production . move_prod_id . id ,
' state ' : ' waiting ' ,
2010-05-25 12:36:48 +00:00
' production_id ' : production . id
2010-05-11 05:35:06 +00:00
}
2010-10-12 06:17:07 +00:00
self . pool . get ( ' stock.move ' ) . create ( cr , uid , data )
2010-05-11 05:35:06 +00:00
return picking_id
2008-10-10 13:36:46 +00:00
2011-11-09 15:10:38 +00:00
def _get_subproduct_factor ( self , cr , uid , production_id , move_id = None , context = None ) :
""" Compute the factor to compute the qty of procucts to produce for the given production_id. By default,
it ' s always equal to the quantity encoded in the production order or the production wizard, but with
2012-10-08 10:28:36 +00:00
the module mrp_byproduct installed it can differ for byproducts having type ' variable ' .
2011-11-09 15:10:38 +00:00
: param production_id : ID of the mrp . order
: param move_id : ID of the stock move that needs to be produced . Identify the product to produce .
: return : The factor to apply to the quantity that we should produce for the given production order and stock move .
2011-11-09 10:01:06 +00:00
"""
2011-08-17 09:18:26 +00:00
sub_obj = self . pool . get ( ' mrp.subproduct ' )
2011-08-23 10:27:08 +00:00
move_obj = self . pool . get ( ' stock.move ' )
production_obj = self . pool . get ( ' mrp.production ' )
2011-11-09 15:10:38 +00:00
production_browse = production_obj . browse ( cr , uid , production_id , context = context )
move_browse = move_obj . browse ( cr , uid , move_id , context = context )
subproduct_factor = 1
sub_id = sub_obj . search ( cr , uid , [ ( ' product_id ' , ' = ' , move_browse . product_id . id ) , ( ' bom_id ' , ' = ' , production_browse . bom_id . id ) , ( ' subproduct_type ' , ' = ' , ' variable ' ) ] , context = context )
2011-08-17 09:18:26 +00:00
if sub_id :
2011-11-09 15:10:38 +00:00
subproduct_record = sub_obj . browse ( cr , uid , sub_id [ 0 ] , context = context )
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 , production_id , move_id , context = context )
2011-08-17 09:18:26 +00:00
2008-10-10 13:36:46 +00:00
mrp_production ( )
2012-02-14 15:57:46 +00:00
class change_production_qty ( osv . osv_memory ) :
_inherit = ' change.production.qty '
def _update_product_to_produce ( self , cr , uid , prod , qty , context = None ) :
bom_obj = self . pool . get ( ' mrp.bom ' )
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_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 , prod . id , m . id , context = context )
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_qty ' : subproduct_qty } )
2009-03-06 22:18:24 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: