2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2008-06-16 11:00:21 +00:00
##############################################################################
2012-03-22 10:41:24 +00:00
#
2009-01-20 08:48:19 +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-06-16 11:00:21 +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-06-16 11:00:21 +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-06-16 11:00:21 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2012-03-22 10:41:24 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-06-16 11:00:21 +00:00
#
2008-11-03 19:18:56 +00:00
##############################################################################
2008-09-04 16:17:33 +00:00
2012-12-06 14:56:32 +00:00
from openerp . osv import fields , osv
from openerp . tools . translate import _
2006-12-07 13:41:40 +00:00
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2010-03-06 20:52:19 +00:00
2006-12-07 13:41:40 +00:00
# Overloaded stock_picking to manage carriers :
class stock_picking ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = ' stock.picking '
2010-02-10 09:10:17 +00:00
def _cal_weight ( self , cr , uid , ids , name , args , context = None ) :
res = { }
2010-11-19 13:48:01 +00:00
for picking in self . browse ( cr , uid , ids , context = context ) :
2010-09-03 22:38:14 +00:00
total_weight = total_weight_net = 0.00
2010-09-06 15:13:25 +00:00
2010-03-11 12:03:01 +00:00
for move in picking . move_lines :
total_weight + = move . weight
2010-09-03 22:38:14 +00:00
total_weight_net + = move . weight_net
2010-09-06 15:13:25 +00:00
2010-09-03 22:38:14 +00:00
res [ picking . id ] = {
2010-09-06 15:13:25 +00:00
' weight ' : total_weight ,
' weight_net ' : total_weight_net ,
}
2010-02-10 09:10:17 +00:00
return res
def _get_picking_line ( self , cr , uid , ids , context = None ) :
result = { }
for line in self . pool . get ( ' stock.move ' ) . browse ( cr , uid , ids , context = context ) :
result [ line . picking_id . id ] = True
return result . keys ( )
2012-03-22 10:41:24 +00:00
2013-07-25 14:43:35 +00:00
2008-07-22 15:11:28 +00:00
_columns = {
' carrier_id ' : fields . many2one ( " delivery.carrier " , " Carrier " ) ,
' volume ' : fields . float ( ' Volume ' ) ,
2011-07-01 23:41:24 +00:00
' weight ' : fields . function ( _cal_weight , type = ' float ' , string = ' Weight ' , digits_compute = dp . get_precision ( ' Stock Weight ' ) , multi = ' _cal_weight ' ,
2010-09-03 22:38:14 +00:00
store = {
2014-09-19 07:35:23 +00:00
' stock.picking ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' move_lines ' ] , 40 ) ,
' stock.move ' : ( _get_picking_line , [ ' picking_id ' , ' product_id ' , ' product_uom_qty ' , ' product_uom ' ] , 40 ) ,
2010-09-03 22:38:14 +00:00
} ) ,
2011-07-01 23:41:24 +00:00
' weight_net ' : fields . function ( _cal_weight , type = ' float ' , string = ' Net Weight ' , digits_compute = dp . get_precision ( ' Stock Weight ' ) , multi = ' _cal_weight ' ,
2010-02-10 09:10:17 +00:00
store = {
2014-09-19 07:35:23 +00:00
' stock.picking ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' move_lines ' ] , 40 ) ,
' stock.move ' : ( _get_picking_line , [ ' picking_id ' , ' product_id ' , ' product_uom_qty ' , ' product_uom ' ] , 40 ) ,
2010-02-10 09:10:17 +00:00
} ) ,
2014-05-21 09:52:05 +00:00
' carrier_tracking_ref ' : fields . char ( ' Carrier Tracking Ref ' ) ,
2010-07-15 19:02:37 +00:00
' number_of_packages ' : fields . integer ( ' Number of Packages ' ) ,
2012-12-14 15:11:08 +00:00
' weight_uom_id ' : fields . many2one ( ' product.uom ' , ' Unit of Measure ' , required = True , readonly = " 1 " , help = " Unit of measurement for Weight " , ) ,
2014-05-07 16:59:51 +00:00
}
2006-12-07 13:41:40 +00:00
2011-12-21 18:11:49 +00:00
def _prepare_shipping_invoice_line ( self , cr , uid , picking , invoice , context = None ) :
""" Prepare the invoice line to add to the shipping costs to the shipping ' s
invoice .
: param browse_record picking : the stock picking being invoiced
: param browse_record invoice : the stock picking ' s invoice
: return : dict containing the values to create the invoice line ,
or None to create nothing
"""
carrier_obj = self . pool . get ( ' delivery.carrier ' )
grid_obj = self . pool . get ( ' delivery.grid ' )
if not picking . carrier_id or \
any ( inv_line . product_id . id == picking . carrier_id . product_id . id
for inv_line in invoice . invoice_line ) :
return None
grid_id = carrier_obj . grid_get ( cr , uid , [ picking . carrier_id . id ] ,
2012-03-30 08:11:36 +00:00
picking . partner_id . id , context = context )
2011-12-21 18:11:49 +00:00
if not grid_id :
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) ,
2011-12-21 18:11:49 +00:00
_ ( ' The carrier %s (id: %d ) has no delivery grid! ' ) \
% ( picking . carrier_id . name ,
picking . carrier_id . id ) )
2014-08-27 15:13:14 +00:00
quantity = sum ( [ line . product_uom_qty for line in picking . move_lines ] )
2011-12-21 18:11:49 +00:00
price = grid_obj . get_price_from_picking ( cr , uid , grid_id ,
invoice . amount_untaxed , picking . weight , picking . volume ,
2014-08-27 15:13:14 +00:00
quantity , context = context )
2011-12-21 18:11:49 +00:00
account_id = picking . carrier_id . product_id . property_account_income . id
if not account_id :
account_id = picking . carrier_id . product_id . categ_id \
. property_account_income_categ . id
taxes = picking . carrier_id . product_id . taxes_id
2012-03-30 08:11:36 +00:00
partner = picking . partner_id or False
2011-12-21 18:11:49 +00:00
if partner :
account_id = self . pool . get ( ' account.fiscal.position ' ) . map_account ( cr , uid , partner . property_account_position , account_id )
taxes_ids = self . pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , partner . property_account_position , taxes )
else :
taxes_ids = [ x . id for x in taxes ]
return {
' name ' : picking . carrier_id . name ,
' invoice_id ' : invoice . id ,
' uos_id ' : picking . carrier_id . product_id . uos_id . id ,
' product_id ' : picking . carrier_id . product_id . id ,
' account_id ' : account_id ,
' price_unit ' : price ,
' quantity ' : 1 ,
' invoice_line_tax_id ' : [ ( 6 , 0 , taxes_ids ) ] ,
}
2013-09-09 14:23:50 +00:00
def _create_invoice_from_picking ( self , cr , uid , picking , vals , context = None ) :
2014-11-06 10:40:04 +00:00
invoice_obj = self . pool . get ( ' account.invoice ' )
2012-03-22 10:41:24 +00:00
invoice_line_obj = self . pool . get ( ' account.invoice.line ' )
2013-09-09 14:23:50 +00:00
invoice_id = super ( stock_picking , self ) . _create_invoice_from_picking ( cr , uid , picking , vals , context = context )
2014-11-06 10:40:04 +00:00
invoice = invoice_obj . browse ( cr , uid , invoice_id , context = context )
2013-09-09 14:23:50 +00:00
invoice_line = self . _prepare_shipping_invoice_line ( cr , uid , picking , invoice , context = context )
if invoice_line :
invoice_line_obj . create ( cr , uid , invoice_line )
return invoice_id
2014-05-07 16:59:51 +00:00
def _get_default_uom ( self , cr , uid , context = None ) :
uom_categ_id = self . pool . get ( ' ir.model.data ' ) . xmlid_to_res_id ( cr , uid , ' product.product_uom_categ_kgm ' )
2013-09-09 14:23:50 +00:00
return self . pool . get ( ' product.uom ' ) . search ( cr , uid , [ ( ' category_id ' , ' = ' , uom_categ_id ) , ( ' factor ' , ' = ' , 1 ) ] ) [ 0 ]
2014-05-07 16:59:51 +00:00
2012-11-12 13:33:21 +00:00
_defaults = {
2014-05-07 16:59:51 +00:00
' weight_uom_id ' : lambda self , cr , uid , c : self . _get_default_uom ( cr , uid , c ) ,
2012-11-12 13:33:21 +00:00
}
2008-07-23 14:41:47 +00:00
2010-03-11 12:03:01 +00:00
class stock_move ( osv . osv ) :
_inherit = ' stock.move '
def _cal_move_weight ( self , cr , uid , ids , name , args , context = None ) :
res = { }
uom_obj = self . pool . get ( ' product.uom ' )
2010-11-19 13:48:01 +00:00
for move in self . browse ( cr , uid , ids , context = context ) :
2010-09-03 22:38:14 +00:00
weight = weight_net = 0.00
2010-03-11 12:03:01 +00:00
if move . product_id . weight > 0.00 :
converted_qty = move . product_qty
weight = ( converted_qty * move . product_id . weight )
2010-09-06 15:13:25 +00:00
2010-09-03 22:38:14 +00:00
if move . product_id . weight_net > 0.00 :
weight_net = ( converted_qty * move . product_id . weight_net )
2010-09-06 15:13:25 +00:00
2010-09-03 22:38:14 +00:00
res [ move . id ] = {
' weight ' : weight ,
' weight_net ' : weight_net ,
}
2010-03-11 12:03:01 +00:00
return res
2010-09-06 15:13:25 +00:00
2010-03-11 12:03:01 +00:00
_columns = {
2011-07-01 23:41:24 +00:00
' weight ' : fields . function ( _cal_move_weight , type = ' float ' , string = ' Weight ' , digits_compute = dp . get_precision ( ' Stock Weight ' ) , multi = ' _cal_move_weight ' ,
2010-09-03 22:38:14 +00:00
store = {
2014-09-16 10:05:52 +00:00
' stock.move ' : ( lambda self , cr , uid , ids , c = None : ids , [ ' product_id ' , ' product_uom_qty ' , ' product_uom ' ] , 30 ) ,
2010-09-03 22:38:14 +00:00
} ) ,
2011-07-01 23:41:24 +00:00
' weight_net ' : fields . function ( _cal_move_weight , type = ' float ' , string = ' Net weight ' , digits_compute = dp . get_precision ( ' Stock Weight ' ) , multi = ' _cal_move_weight ' ,
2010-03-11 12:03:01 +00:00
store = {
2014-09-16 10:05:52 +00:00
' stock.move ' : ( lambda self , cr , uid , ids , c = None : ids , [ ' product_id ' , ' product_uom_qty ' , ' product_uom ' ] , 30 ) ,
2010-03-11 12:03:01 +00:00
} ) ,
2012-12-04 10:58:29 +00:00
' weight_uom_id ' : fields . many2one ( ' product.uom ' , ' Unit of Measure ' , required = True , readonly = " 1 " , help = " Unit of Measure (Unit of Measure) is the unit of measurement for Weight " , ) ,
2010-03-11 12:03:01 +00:00
}
2014-05-07 16:59:51 +00:00
2014-11-05 10:45:04 +00:00
def action_confirm ( self , cr , uid , ids , context = None ) :
2014-11-04 16:28:43 +00:00
"""
Pass the carrier to the picking from the sales order
( Should also work in case of Phantom BoMs when on explosion the original move is deleted )
"""
procs_to_check = [ ]
for move in self . browse ( cr , uid , ids , context = context ) :
if move . procurement_id and move . procurement_id . sale_line_id and move . procurement_id . sale_line_id . order_id . carrier_id :
procs_to_check + = [ move . procurement_id ]
2014-11-05 10:45:04 +00:00
res = super ( stock_move , self ) . action_confirm ( cr , uid , ids , context = context )
pick_obj = self . pool . get ( " stock.picking " )
2014-11-04 16:28:43 +00:00
for proc in procs_to_check :
pickings = list ( set ( [ x . picking_id . id for x in proc . move_ids if x . picking_id and not x . picking_id . carrier_id ] ) )
if pickings :
pick_obj . write ( cr , uid , pickings , { ' carrier_id ' : proc . sale_line_id . order_id . carrier_id . id } , context = context )
2014-11-05 10:45:04 +00:00
return res
2014-05-07 16:59:51 +00:00
def _get_default_uom ( self , cr , uid , context = None ) :
uom_categ_id = self . pool . get ( ' ir.model.data ' ) . xmlid_to_res_id ( cr , uid , ' product.product_uom_categ_kgm ' )
2012-12-14 15:11:08 +00:00
return self . pool . get ( ' product.uom ' ) . search ( cr , uid , [ ( ' category_id ' , ' = ' , uom_categ_id ) , ( ' factor ' , ' = ' , 1 ) ] ) [ 0 ]
2014-05-07 16:59:51 +00:00
2012-12-04 10:58:29 +00:00
_defaults = {
2014-05-07 16:59:51 +00:00
' weight_uom_id ' : lambda self , cr , uid , c : self . _get_default_uom ( cr , uid , c ) ,
2012-12-04 10:58:29 +00:00
}
2010-03-11 12:03:01 +00:00
2012-07-02 09:41:47 +00:00
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: