first commit
This commit is contained in:
118
modules/currency_rs/currency.py
Normal file
118
modules/currency_rs/currency.py
Normal file
@@ -0,0 +1,118 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from decimal import Decimal
|
||||
|
||||
from lxml import objectify
|
||||
from zeep import Client, Transport
|
||||
from zeep.exceptions import Error
|
||||
|
||||
import trytond.config as config
|
||||
from trytond.cache import Cache
|
||||
from trytond.i18n import gettext
|
||||
from trytond.model import fields
|
||||
from trytond.modules.currency.currency import CronFetchError
|
||||
from trytond.pool import Pool, PoolMeta
|
||||
from trytond.pyson import Eval, If
|
||||
|
||||
from .exceptions import RSCredentialWarning
|
||||
|
||||
URL = (
|
||||
'https://webservices.nbs.rs/CommunicationOfficeService1_0/'
|
||||
'ExchangeRateXmlService.asmx?WSDL')
|
||||
|
||||
|
||||
def get_client(username, password, license_id):
|
||||
timeout = config.getfloat('currency_rs', 'requests_timeout', default=300)
|
||||
client = Client(URL, transport=Transport(operation_timeout=timeout))
|
||||
client.set_default_soapheaders({
|
||||
'AuthenticationHeader': {
|
||||
'UserName': username,
|
||||
'Password': password,
|
||||
'LicenceID': license_id,
|
||||
},
|
||||
})
|
||||
return client
|
||||
|
||||
|
||||
class Cron(metaclass=PoolMeta):
|
||||
__name__ = 'currency.cron'
|
||||
|
||||
_states = {
|
||||
'required': Eval('source') == 'nbs_rs',
|
||||
'invisible': Eval('source') != 'nbs_rs',
|
||||
}
|
||||
|
||||
rs_username = fields.Char("Username", states=_states, strip=False)
|
||||
rs_password = fields.Char("Password", states=_states, strip=False)
|
||||
rs_license_id = fields.Char("License ID", states=_states, strip=False)
|
||||
rs_list_type = fields.Selection(
|
||||
'get_rs_list_types', "List Type", states=_states)
|
||||
_rs_list_types = Cache(__name__ + '.get_rs_list_types', context=False)
|
||||
|
||||
del _states
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super().__setup__()
|
||||
cls.source.selection.append(('nbs_rs', "Serbian National Bank"))
|
||||
cls.currency.domain = [
|
||||
cls.currency.domain or [],
|
||||
If(Eval('source') == 'nbs_rs',
|
||||
('code', '=', 'RSD'),
|
||||
()),
|
||||
]
|
||||
|
||||
@fields.depends('rs_username', 'rs_password', 'rs_license_id')
|
||||
def _rs_client(self):
|
||||
return get_client(
|
||||
self.rs_username, self.rs_password, self.rs_license_id)
|
||||
|
||||
@fields.depends('rs_list_type', methods=['_rs_client'])
|
||||
def get_rs_list_types(self):
|
||||
types = self._rs_list_types.get(None)
|
||||
if types is not None:
|
||||
return types
|
||||
try:
|
||||
client = self._rs_client()
|
||||
response = client.service.GetExchangeRateListType()
|
||||
except Error:
|
||||
return [(self.rs_list_type, self.rs_list_type or "")]
|
||||
types = []
|
||||
data = objectify.fromstring(response)
|
||||
for list_type in data.iterchildren():
|
||||
types.append(
|
||||
(str(list_type.ExchangeRateListTypeID), str(list_type.Name)))
|
||||
self._rs_list_types.set(None, types)
|
||||
return types
|
||||
|
||||
def fetch_nbs_rs(self, date):
|
||||
try:
|
||||
client = self._rs_client()
|
||||
response = client.service.GetExchangeRateByDate(
|
||||
date.strftime('%Y%m%d'), self.rs_list_type)
|
||||
except Error as e:
|
||||
raise CronFetchError() from e
|
||||
data = objectify.fromstring(response)
|
||||
return {
|
||||
r.CurrencyCodeAlfaChar: (
|
||||
Decimal(r.Unit.text) / Decimal(r.MiddleRate.text))
|
||||
for r in data.iterchildren()
|
||||
if r.Date == date.strftime('%d.%m.%Y')}
|
||||
|
||||
@classmethod
|
||||
def check_modification(cls, mode, crons, values=None, external=False):
|
||||
pool = Pool()
|
||||
Warning = pool.get('res.user.warning')
|
||||
|
||||
super().check_modification(
|
||||
mode, crons, values=values, external=external)
|
||||
|
||||
if (mode == 'write'
|
||||
and external
|
||||
and values.keys() & {
|
||||
'rs_username', 'rs_password', 'rs_license_id'}):
|
||||
warning_name = Warning.format('rs_credential', crons)
|
||||
if Warning.check(warning_name):
|
||||
raise RSCredentialWarning(
|
||||
warning_name,
|
||||
gettext('currency_rs.msg_rs_credential_modified'))
|
||||
Reference in New Issue
Block a user