Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

15.0 #10

Open
wants to merge 7 commits into
base: 15.0
Choose a base branch
from
108 changes: 108 additions & 0 deletions currency_rate_update_nbu/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
========================
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readme is to be added to a separate folder and split into parts, this README.rst will be regenerated by the bot after the merge
example
https://github.com/OCA/l10n-ukraine/tree/12.0/account_bank_statement_import_online_ua_pb_interpay/readme

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Implemented.

Currency Rate Update NBU
========================

This module provides base for building exchange rates providers and bundles
following built-in providers:

* **National Bank of Ukraine**:
the official currency rate of the Ukrainian hryvnia to foreign currencies.
Source in UAH, for more details see `corresponding
NBU page <https://bank.gov.ua/ua/open-data/api-dev>`_.

This module is compatible with ``currency_rate_inverted`` module provided by
OCA, that allows to maintain exchange rates in inverted format, helping to
resolve rounding issues.

**Table of contents**

.. contents::
:local:

Configuration
=============

To enable scheduled currency rates update:

# Go to *Invoicing > Configuration > Settings*
# Ensure *Automatic Currency Rates (OCA)* is checked

To configure currency rates providers:

# Go to *Invoicing > Configuration > Currency Rates Providers*
# The default NBU provider will be added during module installation with two
available currencies: USD, EUR.

Usage
=====

To update historical currency rates:

# Go to *Invoicing > Configuration > Currency Rates Providers*
# Select the "National Bank of Ukraine" provider
# Add or remove available currencies if you need.
# Launch *Actions > Update Rates Wizard*
# Configure date interval and click *Update*

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/l10n-ukraine/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/l10n-ukraine/issues/new?body=module:%20currency_rate_update_nbu%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* GarazdCreation

Contributors
~~~~~~~~~~~~

* Yurii Razumovskyi <garazdcreation@gmail.com>
* Nicolas Bessi <nicolas.bessi@camptocamp.com>
* Jean-Baptiste Aubort <jean-baptiste.aubort@camptocamp.com>
* Joël Grand-Guillaume <joel.grandguillaume@camptocamp.com>
* Grzegorz Grzelak <grzegorz.grzelak@openglobe.pl> (ECB, NBP)
* Vincent Renaville <vincent.renaville@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Lorenzo Battistini <lorenzo.battistini@agilebg.com> (Port to V7)
* Agustin Cruz <openpyme.mx> (BdM)
* Jacque-Etienne Baudoux <je@bcim.be>
* Juan Jose Scarafia <jjscarafia@paintballrosario.com.ar>
* Mathieu Benoi <mathben963@gmail.com>
* Fekete Mihai <feketemihai@gmail.com> (Port to V8)
* Dorin Hongu <dhongu@gmail.com> (BNR)
* Paul McDermott
* Alexis de Lattre <alexis@via.ecp.fr>
* Miku Laitinen
* Assem Bayahi
* Daniel Dico <ddico@oerp.ca> (BOC)
* Dmytro Katyukha <firemage.dima@gmail.com>
* Jesús Ventosinos Mayor <jesus@comunitea.com>
* `CorporateHub <https://corporatehub.eu/>`__
* Alexey Pelykh <alexey.pelykh@corphub.eu>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have doubts about list contributors

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, the list is changed.


Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/l10n-ukraine <https://github.com/OCA/l10n-ukraine/tree/14.0/currency_rate_update_nbu>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions currency_rate_update_nbu/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
22 changes: 22 additions & 0 deletions currency_rate_update_nbu/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2022 Garazd Creation (https://garazd.biz)
# @author: Yurii Razumovskyi (garazdcreation@gmail.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Currency Rate Update NBU",
"version": "15.0.1.0.0",
"category": "Accounting & Finance",
"summary": "Allows to download currency exchange rates from "
"National Bank of Ukraine",
"author": "Garazd Creation, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/l10n-ukraine",
"license": "AGPL-3",
"depends": [
"currency_rate_update",
],
"data": [
"data/res_currency_rate_provider_data.xml",
"data/ir_config_parameter_data.xml",
],
"installable": True,
}
13 changes: 13 additions & 0 deletions currency_rate_update_nbu/data/ir_config_parameter_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">

<record
id="param_currency_rate_provider_nbu"
model="ir.config_parameter"
forcecreate="True"
>
<field name="key">currency_rate_update_nbu.api_url</field>
<field name="value">https://bank.gov.ua/NBU_Exchange/exchange_site?json</field>
</record>

</odoo>
13 changes: 13 additions & 0 deletions currency_rate_update_nbu/data/res_currency_rate_provider_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">

<record id="res_currency_rate_provider_nbu" model="res.currency.rate.provider">
<field name="name">National Bank of Ukraine</field>
<field name="service">NBU</field>
<field
name="currency_ids"
eval="[(4, ref('base.USD')), (4, ref('base.EUR'))]"
/>
</record>

</odoo>
1 change: 1 addition & 0 deletions currency_rate_update_nbu/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_currency_rate_provider_nbu
104 changes: 104 additions & 0 deletions currency_rate_update_nbu/models/res_currency_rate_provider_nbu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Copyright 2022 Garazd Creation (https://garazd.biz)
# @author: Yurii Razumovskyi (garazdcreation@gmail.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import json
import logging
from collections import defaultdict
from typing import List

import dateutil.parser
import requests
from requests.exceptions import Timeout, TooManyRedirects

from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo.tools.float_utils import float_compare

_logger = logging.getLogger(__name__)


class ResCurrencyRateProviderNBU(models.Model):
"""Implementation for National Bank of Ukraine"""

_inherit = "res.currency.rate.provider"

service = fields.Selection(
selection_add=[("NBU", "National Bank of Ukraine")],
ondelete={"NBU": "set default"},
)

def _get_supported_currencies(self):
self.ensure_one()
if self.service != "NBU":
return super()._get_supported_currencies()
# List of currencies obrained from:
# https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json
return self._nbu_get_available_currencies()

def _nbu_process_request(self, params=None, headers=None):
try:
url = self.env["ir.config_parameter"].get_param(
"currency_rate_update_nbu.api_url"
)
response = requests.get(url=url, params=params, headers=headers, timeout=60)
response_data = json.loads(response.text)
if response.status_code != 200:
raise Exception(
_(
"Failed to fetch from https://bank.gov.ua/ "
"with error code: %s and error message: %s"
)
% (response.status_code, response.reason)
)
except (ConnectionError, Timeout, TooManyRedirects) as e:
raise Exception(str(e))
return response_data

def _nbu_get_available_currencies(self):
"""Get available currency list from NBU.
:return: list of currency codes
"""
data = self._nbu_process_request()
return [cur["cc"] for cur in data]

def _nbu_get_rate(
self, currencies: List, date_from, date_to, invert_calculation=True
):
"""Get currency rates from NBU.
:param currencies: list or currency codes to return
:param date_from: date from which rates will be given
:param date_to: date to which rates will be given
:return: dict
"""
content = defaultdict(dict)
params = {
"start": date_from.strftime("%Y%m%d"),
"end": date_to.strftime("%Y%m%d"),
"sort": "exchangedate",
"order": "asc",
}
data = self._nbu_process_request(params=params)
for line in data:
currency = line.get("cc")
if currency in currencies:
timestamp = fields.Date.to_string(
dateutil.parser.parse(line.get("exchangedate"), dayfirst=True)
)
rate = float(line.get("rate", 0))
if invert_calculation:
rate = 1.0 / rate
content[timestamp].update({currency: rate})
return content

@api.model
def _obtain_rates(self, base_currency, currencies, date_from, date_to):
self.ensure_one()
if self.service != "NBU":
return super()._obtain_rates(base_currency, currencies, date_from, date_to)
if base_currency != self.env.ref("base.UAH").name:
raise UserError(
_('The base company currency should be "UAH" to get NBU rates.')
)
if float_compare(self.env.ref("base.UAH").rate, 1.0, precision_digits=12) != 0:
raise UserError(_("The base company currency rate should be equal to 1.0"))
return self._nbu_get_rate(self.currency_ids.mapped("name"), date_from, date_to)
GarazdCreation marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.