2009-10-20 10:52:23 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2010-06-15 13:27:22 +00:00
#
2009-11-27 07:23:48 +00:00
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
2006-12-07 13:41:40 +00:00
#
2008-11-03 18:27:16 +00:00
# This program is free software: you can redistribute it and/or modify
2009-11-27 07:23:48 +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.
2006-12-07 13:41:40 +00:00
#
2008-11-03 18:27:16 +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-11-27 07:23:48 +00:00
# GNU Affero General Public License for more details.
2006-12-07 13:41:40 +00:00
#
2009-11-27 07:23:48 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-06-15 13:27:22 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
import time
import netsvc
from osv import fields , osv
2011-06-28 14:18:53 +00:00
import tools
2006-12-07 13:41:40 +00:00
from tools . misc import currency
2008-07-08 08:13:12 +00:00
from tools . translate import _
2006-12-07 13:41:40 +00:00
class res_currency ( osv . osv ) :
2010-09-06 11:17:51 +00:00
def _current_rate ( self , cr , uid , ids , name , arg , context = None ) :
if context is None :
context = { }
res = { }
2008-07-22 14:24:36 +00:00
if ' date ' in context :
2010-09-06 11:17:51 +00:00
date = context [ ' date ' ]
2008-07-22 14:24:36 +00:00
else :
2010-09-06 11:17:51 +00:00
date = time . strftime ( ' % Y- % m- %d ' )
date = date or time . strftime ( ' % Y- % m- %d ' )
2011-08-30 14:09:36 +00:00
# Convert False values to None ...
currency_rate_type = context . get ( ' currency_rate_type_id ' ) or None
# ... and use 'is NULL' instead of '= some-id'.
2011-08-30 13:20:35 +00:00
operator = ' = ' if currency_rate_type else ' is '
2008-07-22 14:24:36 +00:00
for id in ids :
2011-08-27 22:53:30 +00:00
cr . execute ( " SELECT currency_id, rate FROM res_currency_rate WHERE currency_id = %s AND name <= %s AND currency_rate_type_id " + operator + " %s ORDER BY name desc LIMIT 1 " , ( id , date , currency_rate_type ) )
2008-07-22 14:24:36 +00:00
if cr . rowcount :
2010-09-06 11:17:51 +00:00
id , rate = cr . fetchall ( ) [ 0 ]
res [ id ] = rate
2008-07-22 14:24:36 +00:00
else :
2010-09-06 11:17:51 +00:00
res [ id ] = 0
2008-07-22 14:24:36 +00:00
return res
_name = " res.currency "
_description = " Currency "
_columns = {
2011-02-21 10:15:49 +00:00
# Note: 'code' column was removed as of v6.0, the 'name' should now hold the ISO code.
' name ' : fields . char ( ' Currency ' , size = 32 , required = True , help = " Currency Code (ISO 4217) " ) ,
2011-04-19 13:11:54 +00:00
' symbol ' : fields . char ( ' Symbol ' , size = 3 , help = " Currency sign, to be used when printing amounts. " ) ,
2009-01-26 17:40:29 +00:00
' rate ' : fields . function ( _current_rate , method = True , string = ' Current Rate ' , digits = ( 12 , 6 ) ,
2011-04-19 13:11:54 +00:00
help = ' The rate of the currency to the currency of rate 1. ' ) ,
2008-07-22 14:24:36 +00:00
' rate_ids ' : fields . one2many ( ' res.currency.rate ' , ' currency_id ' , ' Rates ' ) ,
' accuracy ' : fields . integer ( ' Computational Accuracy ' ) ,
2011-04-19 13:11:54 +00:00
' rounding ' : fields . float ( ' Rounding Factor ' , digits = ( 12 , 6 ) ) ,
2008-07-22 14:24:36 +00:00
' active ' : fields . boolean ( ' Active ' ) ,
2009-11-10 12:46:31 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' ) ,
' date ' : fields . date ( ' Date ' ) ,
' base ' : fields . boolean ( ' Base ' )
2008-07-22 14:24:36 +00:00
}
_defaults = {
' active ' : lambda * a : 1 ,
2009-12-23 17:18:19 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' res.currency ' , context = c )
2008-07-22 14:24:36 +00:00
}
2010-11-18 11:11:54 +00:00
_order = " name "
2006-12-07 13:41:40 +00:00
2009-11-10 12:46:31 +00:00
def read ( self , cr , user , ids , fields = None , context = None , load = ' _classic_read ' ) :
2011-07-14 10:45:17 +00:00
res = super ( osv . osv , self ) . read ( cr , user , ids , fields , context , load )
2011-08-30 12:55:21 +00:00
currency_rate_obj = self . pool . get ( ' res.currency.rate ' )
2009-11-10 12:46:31 +00:00
for r in res :
if r . __contains__ ( ' rate_ids ' ) :
rates = r [ ' rate_ids ' ]
if rates :
2011-07-15 05:55:41 +00:00
currency_date = currency_rate_obj . read ( cr , user , rates [ 0 ] , [ ' name ' ] ) [ ' name ' ]
2010-09-06 11:17:51 +00:00
r [ ' date ' ] = currency_date
2009-11-10 12:46:31 +00:00
return res
2011-06-28 09:56:15 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2011-07-04 11:37:58 +00:00
if not ids :
2011-06-28 09:56:15 +00:00
return [ ]
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
2011-07-04 11:22:06 +00:00
reads = self . read ( cr , uid , ids , [ ' name ' , ' symbol ' ] , context = context , load = ' _classic_write ' )
2011-06-28 09:56:15 +00:00
return [ ( x [ ' id ' ] , tools . ustr ( x [ ' name ' ] ) + ( x [ ' symbol ' ] and ( ' ( ' + tools . ustr ( x [ ' symbol ' ] ) + ' ) ' ) or ' ' ) ) for x in reads ]
2008-07-22 14:24:36 +00:00
def round ( self , cr , uid , currency , amount ) :
2008-09-22 10:16:05 +00:00
if currency . rounding == 0 :
return 0.0
else :
2010-04-23 17:08:58 +00:00
# /!\ First member below must be rounded to full unit!
# Do not pass a rounding digits value to round()
return round ( amount / currency . rounding ) * currency . rounding
2006-12-27 16:20:27 +00:00
2008-07-22 14:24:36 +00:00
def is_zero ( self , cr , uid , currency , amount ) :
return abs ( self . round ( cr , uid , currency , amount ) ) < currency . rounding
2007-07-30 13:35:11 +00:00
2010-12-22 16:10:45 +00:00
def _get_conversion_rate ( self , cr , uid , from_currency , to_currency , context = None ) :
2010-09-06 11:17:51 +00:00
if context is None :
context = { }
2011-08-25 11:56:45 +00:00
ctx = context . copy ( )
2011-08-30 13:20:35 +00:00
ctx . update ( { ' currency_rate_type_id ' : ctx . get ( ' currency_rate_type_from ' ) } )
2011-08-27 22:53:30 +00:00
from_currency = self . browse ( cr , uid , from_currency . id , context = ctx )
2011-08-25 11:56:45 +00:00
2011-08-30 13:20:35 +00:00
ctx . update ( { ' currency_rate_type_id ' : ctx . get ( ' currency_rate_type_to ' ) } )
2011-08-27 22:53:30 +00:00
to_currency = self . browse ( cr , uid , to_currency . id , context = ctx )
2011-08-25 11:56:45 +00:00
2011-08-27 22:53:30 +00:00
if from_currency . rate == 0 or to_currency . rate == 0 :
2008-07-22 14:24:36 +00:00
date = context . get ( ' date ' , time . strftime ( ' % Y- % m- %d ' ) )
2011-08-27 22:53:30 +00:00
if from_currency . rate == 0 :
2010-11-19 05:06:26 +00:00
currency_symbol = from_currency . symbol
2008-07-22 14:24:36 +00:00
else :
2010-11-19 05:06:26 +00:00
currency_symbol = to_currency . symbol
2008-07-22 14:24:36 +00:00
raise osv . except_osv ( _ ( ' Error ' ) , _ ( ' No rate found \n ' \
' for the currency: %s \n ' \
2010-11-19 05:06:26 +00:00
' at the date: %s ' ) % ( currency_symbol , date ) )
2010-12-22 16:10:45 +00:00
return to_currency . rate / from_currency . rate
2011-08-19 11:07:19 +00:00
def compute ( self , cr , uid , from_currency_id , to_currency_id , from_amount ,
round = True , currency_rate_type_from = False , currency_rate_type_to = False , context = None ) :
2011-08-24 09:10:22 +00:00
if not context :
context = { }
2010-12-22 16:10:45 +00:00
if not from_currency_id :
from_currency_id = to_currency_id
if not to_currency_id :
to_currency_id = from_currency_id
xc = self . browse ( cr , uid , [ from_currency_id , to_currency_id ] , context = context )
from_currency = ( xc [ 0 ] . id == from_currency_id and xc [ 0 ] ) or xc [ 1 ]
to_currency = ( xc [ 0 ] . id == to_currency_id and xc [ 0 ] ) or xc [ 1 ]
2011-08-30 12:07:27 +00:00
if ( to_currency_id == from_currency_id ) and ( currency_rate_type_from == currency_rate_type_to ) :
2008-07-22 14:24:36 +00:00
if round :
return self . round ( cr , uid , to_currency , from_amount )
else :
return from_amount
else :
2011-08-25 11:56:45 +00:00
context . update ( { ' currency_rate_type_from ' : currency_rate_type_from , ' currency_rate_type_to ' : currency_rate_type_to } )
2010-12-22 16:10:45 +00:00
rate = self . _get_conversion_rate ( cr , uid , from_currency , to_currency , context = context )
2008-07-22 14:24:36 +00:00
if round :
2008-10-23 17:45:49 +00:00
return self . round ( cr , uid , to_currency , from_amount * rate )
2008-07-22 14:24:36 +00:00
else :
2008-10-23 17:45:49 +00:00
return ( from_amount * rate )
2006-12-07 13:41:40 +00:00
res_currency ( )
2011-07-14 09:27:37 +00:00
class res_currency_rate_type ( osv . osv ) :
_name = " res.currency.rate.type "
2011-08-30 12:55:21 +00:00
_description = " Used to define the type of Currency Rates "
2011-07-14 09:27:37 +00:00
_columns = {
2011-08-27 22:53:30 +00:00
' name ' : fields . char ( ' Name ' , size = 64 , required = True , translate = True ) ,
2011-07-14 09:27:37 +00:00
}
res_currency_rate_type ( )
2006-12-19 13:49:50 +00:00
class res_currency_rate ( osv . osv ) :
2008-07-22 14:24:36 +00:00
_name = " res.currency.rate "
_description = " Currency Rate "
2011-08-27 22:53:30 +00:00
2008-07-22 14:24:36 +00:00
_columns = {
' name ' : fields . date ( ' Date ' , required = True , select = True ) ,
' rate ' : fields . float ( ' Rate ' , digits = ( 12 , 6 ) , required = True ,
help = ' The rate of the currency to the currency of rate 1 ' ) ,
' currency_id ' : fields . many2one ( ' res.currency ' , ' Currency ' , readonly = True ) ,
2011-08-30 12:07:27 +00:00
' currency_rate_type_id ' : fields . many2one ( ' res.currency.rate.type ' , ' Currency Rate Type ' , help = " Allow you to define your own currency rate types, like ' Average ' or ' Year to Date ' . Leave empty if you simply want to use the normal ' spot ' rate type " ) ,
2008-07-22 14:24:36 +00:00
}
_defaults = {
' name ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
}
_order = " name desc "
2011-07-14 09:27:37 +00:00
2006-12-19 13:49:50 +00:00
res_currency_rate ( )
2008-07-23 15:01:27 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: