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
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()
|
|
|