You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

134 lines
5.7 KiB

# -*- coding: utf-8 -*-
"""
Convert currency rate based on company currency by using xe.com platform
"""
import requests
from lxml import etree
from odoo import api, fields, models
from odoo.exceptions import UserError
class ResConfigSettings(models.TransientModel):
"""List out the service provider for exchange the currency rate based on our company currency"""
_inherit = 'res.config.settings'
currency_update = fields.Boolean(string='Live Currency Rate Update')
service_provider = fields.Selection(related="company_id.service_provider", readonly=False)
@api.model
def get_values(self):
"""get values from the fields"""
res = super(ResConfigSettings, self).get_values()
res.update(
currency_update=self.env['ir.config_parameter'].sudo().get_param('currency_update'),
service_provider=self.env['ir.config_parameter'].sudo().get_param('service_provider')
)
return res
@api.multi
def set_values(self):
"""Set values in the fields"""
super(ResConfigSettings, self).set_values()
self.env['ir.config_parameter'].sudo().set_param('service_provider', self.service_provider)
self.env['ir.config_parameter'].sudo().set_param('currency_update', self.currency_update)
def update_rate(self):
"""Update the currency rate manually"""
self.ensure_one()
if self.company_id.service_provider != 'xe_com':
raise UserError("Please select a service provider. ")
if not (self.company_id.currency_rate_updates()):
raise UserError('Unable to connect at this this time.'
'Please try again later.')
class ResCompany(models.Model):
"""This class generate the current currency rate from xe.com website"""
_inherit = 'res.company'
service_provider = fields.Selection([
('xe_com', 'xe.com'),
], string='Service', default='xe_com')
@api.multi
def currency_rate_updates(self):
"""This method is used to update all currencies given by the provider."""
result = True
active_currencies = self.env['res.currency'].search([])
for (service_provider, companies) in self.currency_provider().items():
results = None
if service_provider == 'xe_com':
function = getattr(companies, service_provider + '_data')
results = function(active_currencies)
if service_provider != 'xe_com':
raise UserError("Unavailable currency rate web service.")
else:
companies.res_currency_rate(results)
return result
def currency_provider(self):
"""Returns a dictionary the companies in self by currency
rate provider."""
result = {}
for company in self:
if not company.service_provider:
continue
else:
result[company.service_provider] = company
return result
def res_currency_rate(self, data):
"""Generate the entries of currency rates for the company,
using the result of a function, given as parameter, to get the rates data."""
res_currency = self.env['res.currency']
currency_rate = self.env['res.currency.rate']
for company in self:
currency_rate_info = data.get(company.currency_id.name, None)
if not currency_rate_info:
raise UserError(("Main currency %s is not supported by this service provider. "
"Choose another one.") % company.currency_id.name)
base_currency = currency_rate_info[0]
for currency, (rate, date_rate) in data.items():
value = rate/base_currency
currency_object = res_currency.search([('name', '=', currency)])
existing_rate = currency_rate.search([('currency_id', '=', currency_object.id),
('name', '=', date_rate),
('company_id', '=', company.id)])
if existing_rate:
existing_rate.rate = value
else:
currency_rate.create({'currency_id': currency_object.id,
'rate': value,
'name': date_rate,
'company_id': company.id})
def xe_com_data(self, currencies):
"""Import the currency rates data from the xe.com service provider.
As this provider does not have an API, here we directly extract exchange rate
from HTML."""
url = 'http://www.xe.com/currencytables/?from=%(currency_code)s&date=%(date)s'
today = fields.Date.today()
data = requests.request('GET', url % {'currency_code': 'INR', 'date': today})
result = {}
available_currencies = currencies.mapped('name')
html_content = etree.fromstring(data.content, etree.HTMLParser())
table_rate = html_content.find(".//table[@id='historicalRateTbl']/tbody")
for table_entry in list(table_rate):
if type(
table_entry) != etree._Comment:
code = table_entry.find('.//a').text
if code in available_currencies:
rate = float(table_entry.find(
"td[@class='historicalRateTable-rateHeader']").text)
result[code] = (rate, today)
return result
@api.model
def cron_update(self):
"""Update currency rate automatically by using cron job"""
update_company = self.env['res.company'].search([])
update_company.currency_rate_updates()