2010-02-02 06:10:46 +00:00
##############################################################################
#
# OpenERP, Open Source Management Solution
2010-02-05 15:09:27 +00:00
# Copyright (C)
# 2004-2010 Tiny SPRL (<http://tiny.be>).
# 2009-2010 Veritos (http://veritos.nl).
# All Rights Reserved
2010-02-02 06:10:46 +00:00
#
# This program is free software: you can redistribute it and/or modify
# 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.
#
# 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
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2013-12-05 16:34:06 +00:00
from openerp . osv import osv , fields
2010-02-02 06:10:46 +00:00
class account_invoice_line ( osv . osv ) :
_inherit = " account.invoice.line "
2011-05-11 05:50:31 +00:00
2013-12-05 16:34:06 +00:00
_columns = {
' move_id ' : fields . many2one ( ' stock.move ' , string = " Move line " , help = " If the invoice was generated from a stock.picking, reference to the related move line. " ) ,
}
2010-02-02 06:10:46 +00:00
def move_line_get ( self , cr , uid , invoice_id , context = None ) :
2010-11-19 13:48:01 +00:00
res = super ( account_invoice_line , self ) . move_line_get ( cr , uid , invoice_id , context = context )
inv = self . pool . get ( ' account.invoice ' ) . browse ( cr , uid , invoice_id , context = context )
2010-12-21 12:32:02 +00:00
company_currency = inv . company_id . currency_id . id
2013-12-05 16:34:06 +00:00
def get_price ( cr , uid , inv , company_currency , i_line , price_unit ) :
2010-12-21 12:32:02 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
if inv . currency_id . id != company_currency :
2013-12-05 16:34:06 +00:00
price = cur_obj . compute ( cr , uid , company_currency , inv . currency_id . id , price_unit * i_line . quantity , context = { ' date ' : inv . date_invoice } )
2010-12-21 12:32:02 +00:00
else :
2013-12-05 16:34:06 +00:00
price = price_unit * i_line . quantity
2010-12-21 12:32:02 +00:00
return price
2010-02-02 06:10:46 +00:00
if inv . type in ( ' out_invoice ' , ' out_refund ' ) :
for i_line in inv . invoice_line :
2012-11-06 11:02:35 +00:00
if i_line . product_id and i_line . product_id . valuation == ' real_time ' :
2010-02-02 06:10:46 +00:00
if inv . type == ' out_invoice ' :
2010-02-05 15:09:27 +00:00
# debit account dacc will be the output account
2011-05-11 05:50:31 +00:00
# first check the product, if empty check the category
dacc = i_line . product_id . property_stock_account_output and i_line . product_id . property_stock_account_output . id
2010-02-02 06:10:46 +00:00
if not dacc :
dacc = i_line . product_id . categ_id . property_stock_account_output_categ and i_line . product_id . categ_id . property_stock_account_output_categ . id
else :
2010-02-05 15:09:27 +00:00
# = out_refund
# debit account dacc will be the input account
2011-05-11 05:50:31 +00:00
# first check the product, if empty check the category
dacc = i_line . product_id . property_stock_account_input and i_line . product_id . property_stock_account_input . id
2010-02-02 06:10:46 +00:00
if not dacc :
dacc = i_line . product_id . categ_id . property_stock_account_input_categ and i_line . product_id . categ_id . property_stock_account_input_categ . id
2010-02-05 15:09:27 +00:00
# in both cases the credit account cacc will be the expense account
2011-05-11 05:50:31 +00:00
# first check the product, if empty check the category
cacc = i_line . product_id . property_account_expense and i_line . product_id . property_account_expense . id
2010-02-02 06:10:46 +00:00
if not cacc :
cacc = i_line . product_id . categ_id . property_account_expense_categ and i_line . product_id . categ_id . property_account_expense_categ . id
if dacc and cacc :
2013-12-05 16:34:06 +00:00
price_unit = i_line . move_id and i_line . move_id . price_unit or i_line . product_id . standard_price
2010-02-02 06:10:46 +00:00
res . append ( {
' type ' : ' src ' ,
' name ' : i_line . name [ : 64 ] ,
2013-12-05 16:34:06 +00:00
' price_unit ' : price_unit ,
2010-02-02 06:10:46 +00:00
' quantity ' : i_line . quantity ,
2013-12-05 16:34:06 +00:00
' price ' : get_price ( cr , uid , inv , company_currency , i_line , price_unit ) ,
2010-02-02 06:10:46 +00:00
' account_id ' : dacc ,
' product_id ' : i_line . product_id . id ,
' uos_id ' : i_line . uos_id . id ,
2012-02-15 16:06:28 +00:00
' account_analytic_id ' : False ,
2010-02-02 06:10:46 +00:00
' taxes ' : i_line . invoice_line_tax_id ,
} )
2011-05-11 05:50:31 +00:00
2010-02-02 06:10:46 +00:00
res . append ( {
' type ' : ' src ' ,
' name ' : i_line . name [ : 64 ] ,
2013-12-05 16:34:06 +00:00
' price_unit ' : price_unit ,
2010-02-02 06:10:46 +00:00
' quantity ' : i_line . quantity ,
2013-12-05 16:34:06 +00:00
' price ' : - 1 * get_price ( cr , uid , inv , company_currency , i_line , price_unit ) ,
2010-02-02 06:10:46 +00:00
' account_id ' : cacc ,
' product_id ' : i_line . product_id . id ,
' uos_id ' : i_line . uos_id . id ,
2012-02-15 16:06:28 +00:00
' account_analytic_id ' : False ,
2010-02-02 06:10:46 +00:00
' taxes ' : i_line . invoice_line_tax_id ,
} )
elif inv . type in ( ' in_invoice ' , ' in_refund ' ) :
for i_line in inv . invoice_line :
2012-11-06 11:02:35 +00:00
if i_line . product_id and i_line . product_id . valuation == ' real_time ' :
2011-05-11 05:50:31 +00:00
if i_line . product_id . type != ' service ' :
# get the price difference account at the product
acc = i_line . product_id . property_account_creditor_price_difference and i_line . product_id . property_account_creditor_price_difference . id
2010-02-02 06:10:46 +00:00
if not acc :
2011-05-11 05:50:31 +00:00
# if not found on the product get the price difference account at the category
2010-02-02 06:10:46 +00:00
acc = i_line . product_id . categ_id . property_account_creditor_price_difference_categ and i_line . product_id . categ_id . property_account_creditor_price_difference_categ . id
a = None
if inv . type == ' in_invoice ' :
2010-02-05 15:09:27 +00:00
# oa will be the stock input account
2011-05-11 05:50:31 +00:00
# first check the product, if empty check the category
oa = i_line . product_id . property_stock_account_input and i_line . product_id . property_stock_account_input . id
2010-02-02 06:10:46 +00:00
if not oa :
oa = i_line . product_id . categ_id . property_stock_account_input_categ and i_line . product_id . categ_id . property_stock_account_input_categ . id
else :
2010-02-05 15:09:27 +00:00
# = in_refund
# oa will be the stock output account
2011-05-11 05:50:31 +00:00
# first check the product, if empty check the category
oa = i_line . product_id . property_stock_account_output and i_line . product_id . property_stock_account_output . id
2010-02-02 06:10:46 +00:00
if not oa :
oa = i_line . product_id . categ_id . property_stock_account_output_categ and i_line . product_id . categ_id . property_stock_account_output_categ . id
if oa :
2011-05-11 05:50:31 +00:00
# get the fiscal position
2010-02-02 06:10:46 +00:00
fpos = i_line . invoice_id . fiscal_position or False
a = self . pool . get ( ' account.fiscal.position ' ) . map_account ( cr , uid , fpos , oa )
diff_res = [ ]
2011-05-11 05:50:31 +00:00
# calculate and write down the possible price difference between invoice price and product price
2010-02-02 06:10:46 +00:00
for line in res :
if a == line [ ' account_id ' ] and i_line . product_id . id == line [ ' product_id ' ] :
uom = i_line . product_id . uos_id or i_line . product_id . uom_id
2013-06-24 09:03:29 +00:00
valuation_price_unit = self . pool . get ( ' product.uom ' ) . _compute_price ( cr , uid , uom . id , i_line . product_id . standard_price , i_line . uos_id . id )
if i_line . product_id . cost_method != ' standard ' and i_line . purchase_line_id :
#for average/fifo/lifo costing method, fetch real cost price from incomming moves
stock_move_obj = self . pool . get ( ' stock.move ' )
valuation_stock_move = stock_move_obj . search ( cr , uid , [ ( ' purchase_line_id ' , ' = ' , i_line . purchase_line_id . id ) ] , limit = 1 , context = context )
if valuation_stock_move :
valuation_price_unit = stock_move_obj . browse ( cr , uid , valuation_stock_move [ 0 ] , context = context ) . price_unit
if valuation_price_unit != i_line . price_unit and line [ ' price_unit ' ] == i_line . price_unit and acc :
price_diff = i_line . price_unit - valuation_price_unit
line . update ( { ' price ' : valuation_price_unit * line [ ' quantity ' ] } )
2010-02-02 06:10:46 +00:00
diff_res . append ( {
2013-06-24 09:03:29 +00:00
' type ' : ' src ' ,
2010-02-02 06:10:46 +00:00
' name ' : i_line . name [ : 64 ] ,
2013-06-24 09:03:29 +00:00
' price_unit ' : price_diff ,
' quantity ' : line [ ' quantity ' ] ,
2010-02-02 06:10:46 +00:00
' price ' : price_diff * line [ ' quantity ' ] ,
2013-06-24 09:03:29 +00:00
' account_id ' : acc ,
' product_id ' : line [ ' product_id ' ] ,
' uos_id ' : line [ ' uos_id ' ] ,
' account_analytic_id ' : line [ ' account_analytic_id ' ] ,
' taxes ' : line . get ( ' taxes ' , [ ] ) ,
2010-02-02 06:10:46 +00:00
} )
res + = diff_res
2011-05-11 05:50:31 +00:00
return res
2013-01-25 06:32:13 +00:00
def product_id_change ( self , cr , uid , ids , product , uom_id , qty = 0 , name = ' ' , type = ' out_invoice ' , partner_id = False , fposition_id = False , price_unit = False , currency_id = False , context = None , company_id = None ) :
2011-07-25 10:14:24 +00:00
fiscal_pool = self . pool . get ( ' account.fiscal.position ' )
2013-01-25 06:32:13 +00:00
res = super ( account_invoice_line , self ) . product_id_change ( cr , uid , ids , product , uom_id , qty , name , type , partner_id , fposition_id , price_unit , currency_id , context , company_id )
2010-02-02 06:10:46 +00:00
if not product :
2011-07-25 10:14:24 +00:00
return res
2010-02-02 06:10:46 +00:00
if type in ( ' in_invoice ' , ' in_refund ' ) :
product_obj = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product , context = context )
if type == ' in_invoice ' :
2011-05-11 05:50:31 +00:00
oa = product_obj . property_stock_account_input and product_obj . property_stock_account_input . id
2010-02-02 06:10:46 +00:00
if not oa :
oa = product_obj . categ_id . property_stock_account_input_categ and product_obj . categ_id . property_stock_account_input_categ . id
else :
2011-05-11 05:50:31 +00:00
oa = product_obj . property_stock_account_output and product_obj . property_stock_account_output . id
2010-02-02 06:10:46 +00:00
if not oa :
oa = product_obj . categ_id . property_stock_account_output_categ and product_obj . categ_id . property_stock_account_output_categ . id
if oa :
2011-07-25 10:14:24 +00:00
fpos = fposition_id and fiscal_pool . browse ( cr , uid , fposition_id , context = context ) or False
a = fiscal_pool . map_account ( cr , uid , fpos , oa )
2011-05-11 05:50:31 +00:00
res [ ' value ' ] . update ( { ' account_id ' : a } )
2010-02-02 06:10:46 +00:00
return res
2011-05-11 05:50:31 +00:00
2010-02-02 06:10:46 +00:00
class account_invoice ( osv . osv ) :
_inherit = " account.invoice "
2012-12-19 01:04:29 +00:00
def _prepare_refund ( self , cr , uid , invoice , date = None , period_id = None , description = None , journal_id = None , context = None ) :
invoice_data = super ( account_invoice , self ) . _prepare_refund ( cr , uid , invoice , date , period_id ,
description , journal_id , context = context )
if invoice . type == ' in_invoice ' :
fiscal_position = self . pool . get ( ' account.fiscal.position ' )
for _ , _ , line_dict in invoice_data [ ' invoice_line ' ] :
if line_dict . get ( ' product_id ' ) :
product = self . pool . get ( ' product.product ' ) . browse ( cr , uid , line_dict [ ' product_id ' ] , context = context )
counterpart_acct_id = product . property_stock_account_output and \
product . property_stock_account_output . id
if not counterpart_acct_id :
counterpart_acct_id = product . categ_id . property_stock_account_output_categ and \
product . categ_id . property_stock_account_output_categ . id
if counterpart_acct_id :
fpos = invoice . fiscal_position or False
line_dict [ ' account_id ' ] = fiscal_position . map_account ( cr , uid ,
fpos ,
counterpart_acct_id )
return invoice_data
2011-05-11 05:50:31 +00:00
2010-09-01 16:58:41 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: