Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[16.0][ADD] currency_rate_update_nbu #11

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions currency_rate_update_nbu/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
========================
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 <[email protected]>

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 2023 Garazd Creation (https://garazd.biz)
# @author: Yurii Razumovskyi ([email protected])
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

{
"name": "Currency Rate Update NBU",
"version": "16.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 2023 Garazd Creation (https://garazd.biz)
# @author: Yurii Razumovskyi ([email protected])
# 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: %(code)s and error message: %(msg)s"
)
% {"code": response.status_code, "msg": response.reason}
)
except (ConnectionError, Timeout, TooManyRedirects) as e:
raise Exception(str(e)) from 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(currencies, date_from, date_to)
9 changes: 9 additions & 0 deletions currency_rate_update_nbu/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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.
3 changes: 3 additions & 0 deletions currency_rate_update_nbu/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Garazd Creation <https://garazd.biz/>`__

* Yurii Razumovskyi <[email protected]>
11 changes: 11 additions & 0 deletions currency_rate_update_nbu/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
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.
7 changes: 7 additions & 0 deletions currency_rate_update_nbu/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
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*
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions oca_dependencies.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt
currency
6 changes: 6 additions & 0 deletions setup/currency_rate_update_nbu/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)