From 4f5c8aad0561fd25338936743ac61cb4ad1d85b9 Mon Sep 17 00:00:00 2001 From: Ernesto Tejeda Date: Mon, 10 Apr 2023 15:42:23 +0200 Subject: [PATCH 1/8] [ADD] currency_rate_update_xe: new module --- currency_rate_update_xe/README.rst | 92 ++++ currency_rate_update_xe/__init__.py | 3 + currency_rate_update_xe/__manifest__.py | 17 + .../i18n/currency_rate_update_xe.pot | 37 ++ currency_rate_update_xe/i18n/es.po | 39 ++ currency_rate_update_xe/models/__init__.py | 2 + .../models/res_currency_rate_provider_XE.py | 271 +++++++++++ currency_rate_update_xe/readme/CONFIGURE.rst | 9 + .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 5 + .../static/description/icon.png | Bin 0 -> 6482 bytes .../static/description/index.html | 439 ++++++++++++++++++ currency_rate_update_xe/tests/__init__.py | 3 + .../tests/test_currency_rate_update_xe.py | 52 +++ 14 files changed, 972 insertions(+) create mode 100644 currency_rate_update_xe/README.rst create mode 100644 currency_rate_update_xe/__init__.py create mode 100644 currency_rate_update_xe/__manifest__.py create mode 100644 currency_rate_update_xe/i18n/currency_rate_update_xe.pot create mode 100644 currency_rate_update_xe/i18n/es.po create mode 100644 currency_rate_update_xe/models/__init__.py create mode 100644 currency_rate_update_xe/models/res_currency_rate_provider_XE.py create mode 100644 currency_rate_update_xe/readme/CONFIGURE.rst create mode 100644 currency_rate_update_xe/readme/CONTRIBUTORS.rst create mode 100644 currency_rate_update_xe/readme/DESCRIPTION.rst create mode 100644 currency_rate_update_xe/static/description/icon.png create mode 100644 currency_rate_update_xe/static/description/index.html create mode 100644 currency_rate_update_xe/tests/__init__.py create mode 100644 currency_rate_update_xe/tests/test_currency_rate_update_xe.py diff --git a/currency_rate_update_xe/README.rst b/currency_rate_update_xe/README.rst new file mode 100644 index 00000000..ebcdb045 --- /dev/null +++ b/currency_rate_update_xe/README.rst @@ -0,0 +1,92 @@ +============================ +Currency Rate Update: XE.com +============================ + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcurrency-lightgray.png?logo=github + :target: https://github.com/OCA/currency/tree/15.0/currency_rate_update_xe + :alt: OCA/currency +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/currency-15-0/currency-15-0-currency_rate_update_xe + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/currency&target_branch=15.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds `XE.com `_ currency exchange rates provider. + +Disclaimer: The rates are fetched by scraping the corresponding web page. +Being a public page, it's legal according sentences like +https://seointel.com/news/the-court-determines-that-data-scraping-is-legal-on-linkedin/ + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Now you can choose the 'XE.com' service when configuring +a currency rates providers. + +#. Go to *Invoicing > Configuration > Currency Rates Providers*. +#. Create a new 'Currency Rates Providers' or edit an existing + one and you will see 'XE.com' among the available + 'Source Services' to choose. +#. If you choose 'XE.com' as a 'Source Service', the exchange rates + will be updated from that provider. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_: + + * Ernesto Tejeda + +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/currency `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/currency_rate_update_xe/__init__.py b/currency_rate_update_xe/__init__.py new file mode 100644 index 00000000..4b76c7b2 --- /dev/null +++ b/currency_rate_update_xe/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/currency_rate_update_xe/__manifest__.py b/currency_rate_update_xe/__manifest__.py new file mode 100644 index 00000000..ed52cb0c --- /dev/null +++ b/currency_rate_update_xe/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2023 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Currency Rate Update: XE.com", + "version": "15.0.1.0.0", + "category": "Financial Management/Configuration", + "summary": "Update exchange rates using XE.com", + "author": "Tecnativa, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/currency", + "license": "AGPL-3", + "installable": True, + "application": False, + "depends": [ + "currency_rate_update", + ], +} diff --git a/currency_rate_update_xe/i18n/currency_rate_update_xe.pot b/currency_rate_update_xe/i18n/currency_rate_update_xe.pot new file mode 100644 index 00000000..a09e3226 --- /dev/null +++ b/currency_rate_update_xe/i18n/currency_rate_update_xe.pot @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * currency_rate_update_xe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-04-11 07:38+0000\n" +"PO-Revision-Date: 2023-04-11 07:38+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: currency_rate_update_xe +#: code:addons/currency_rate_update_xe/models/res_currency_rate_provider_XE.py:0 +#, python-format +msgid "Couldn't fetch data. Please contact your administrator." +msgstr "" + +#. module: currency_rate_update_xe +#: model:ir.model,name:currency_rate_update_xe.model_res_currency_rate_provider +msgid "Currency Rates Provider" +msgstr "" + +#. module: currency_rate_update_xe +#: model:ir.model.fields,field_description:currency_rate_update_xe.field_res_currency_rate_provider__service +msgid "Source Service" +msgstr "" + +#. module: currency_rate_update_xe +#: model:ir.model.fields.selection,name:currency_rate_update_xe.selection__res_currency_rate_provider__service__xe +msgid "XE.com" +msgstr "" diff --git a/currency_rate_update_xe/i18n/es.po b/currency_rate_update_xe/i18n/es.po new file mode 100644 index 00000000..9f5df101 --- /dev/null +++ b/currency_rate_update_xe/i18n/es.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * currency_rate_update_xe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-04-11 07:38+0000\n" +"PO-Revision-Date: 2023-04-11 09:42+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 3.0.1\n" + +#. module: currency_rate_update_xe +#: code:addons/currency_rate_update_xe/models/res_currency_rate_provider_XE.py:0 +#, python-format +msgid "Couldn't fetch data. Please contact your administrator." +msgstr "No se pudieron obtener los datos. Por favor, contacte a su administrador." + +#. module: currency_rate_update_xe +#: model:ir.model,name:currency_rate_update_xe.model_res_currency_rate_provider +msgid "Currency Rates Provider" +msgstr "Proveedor de Tipos de Cambio" + +#. module: currency_rate_update_xe +#: model:ir.model.fields,field_description:currency_rate_update_xe.field_res_currency_rate_provider__service +msgid "Source Service" +msgstr "Servicio Fuente" + +#. module: currency_rate_update_xe +#: model:ir.model.fields.selection,name:currency_rate_update_xe.selection__res_currency_rate_provider__service__xe +msgid "XE.com" +msgstr "" diff --git a/currency_rate_update_xe/models/__init__.py b/currency_rate_update_xe/models/__init__.py new file mode 100644 index 00000000..c974c884 --- /dev/null +++ b/currency_rate_update_xe/models/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import res_currency_rate_provider_XE diff --git a/currency_rate_update_xe/models/res_currency_rate_provider_XE.py b/currency_rate_update_xe/models/res_currency_rate_provider_XE.py new file mode 100644 index 00000000..b18a2abc --- /dev/null +++ b/currency_rate_update_xe/models/res_currency_rate_provider_XE.py @@ -0,0 +1,271 @@ +# Copyright 2023 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from datetime import date, timedelta + +import requests +from lxml import etree + +from odoo import _, fields, models +from odoo.exceptions import UserError + + +class ResCurrencyRateProviderXE(models.Model): + _inherit = "res.currency.rate.provider" + + service = fields.Selection( + selection_add=[("XE", "XE.com")], + ondelete={"XE": "set default"}, + ) + + def _get_supported_currencies(self): + self.ensure_one() + if self.service != "XE": + return super()._get_supported_currencies() + # List of currencies obrained from: https://www.xe.com/currency/ + return [ + "USD", + "EUR", + "GBP", + "CAD", + "AUD", + "JPY", + "ADA", + "AED", + "AFN", + "ALL", + "AMD", + "ANG", + "AOA", + "ARS", + "AUD", + "AWG", + "AZN", + "BAM", + "BBD", + "BCH", + "BDT", + "BGN", + "BHD", + "BIF", + "BMD", + "BND", + "BOB", + "BRL", + "BSD", + "BTC", + "BTN", + "BWP", + "BYN", + "BYR", + "BZD", + "CAD", + "CDF", + "CHF", + "CLP", + "CNY", + "COP", + "CRC", + "CUC", + "CUP", + "CVE", + "CZK", + "DJF", + "DKK", + "DOGE", + "DOP", + "DOT", + "DZD", + "EEK", + "EGP", + "ERN", + "ETB", + "ETH", + "EUR", + "FJD", + "FKP", + "GBP", + "GEL", + "GGP", + "GHS", + "GIP", + "GMD", + "GNF", + "GTQ", + "GYD", + "HKD", + "HNL", + "HRK", + "HTG", + "HUF", + "IDR", + "ILS", + "IMP", + "INR", + "IQD", + "IRR", + "ISK", + "JEP", + "JMD", + "JOD", + "JPY", + "KES", + "KGS", + "KHR", + "KMF", + "KPW", + "KRW", + "KWD", + "KYD", + "KZT", + "LAK", + "LBP", + "LINK", + "LKR", + "LRD", + "LSL", + "LTC", + "LTL", + "LUNA", + "LVL", + "LYD", + "MAD", + "MDL", + "MGA", + "MKD", + "MMK", + "MNT", + "MOP", + "MRU", + "MUR", + "MVR", + "MWK", + "MXN", + "MYR", + "MZN", + "NAD", + "NGN", + "NIO", + "NOK", + "NPR", + "NZD", + "OMR", + "PAB", + "PEN", + "PGK", + "PHP", + "PKR", + "PLN", + "PYG", + "QAR", + "RON", + "RSD", + "RUB", + "RWF", + "SAR", + "SBD", + "SCR", + "SDG", + "SEK", + "SGD", + "SHP", + "SLE", + "SLL", + "SOS", + "SPL", + "SRD", + "STN", + "SVC", + "SYP", + "SZL", + "THB", + "TJS", + "TMT", + "TND", + "TOP", + "TRY", + "TTD", + "TVD", + "TWD", + "TZS", + "UAH", + "UGX", + "UNI", + "USD", + "UYU", + "UZS", + "VEF", + "VES", + "VND", + "VUV", + "WST", + "XAF", + "XAG", + "XAU", + "XCD", + "XDR", + "XLM", + "XOF", + "XPD", + "XPF", + "XPT", + "XRP", + "YER", + "ZAR", + "ZMK", + "ZMW", + "ZWD", + ] + + def _obtain_rates(self, base_currency, currencies, date_from, date_to): + self.ensure_one() + if self.service != "XE": + return super()._obtain_rates(base_currency, currencies, date_from, date_to) + base_url = "http://www.xe.com/currencytables" + if date_from < date.today(): + return self._get_historical_rate( + base_url, currencies, date_from, date_to, base_currency + ) + else: + return self._get_latest_rate(base_url, currencies, base_currency) + + def _get_latest_rate(self, base_url, currencies, base_currency): + """Get all the exchange rates for today""" + url = f"{base_url}/?from={base_currency}" + data = self._request_data(url) + return {date.today(): self._parse_data(data, currencies)} + + def _get_historical_rate( + self, base_url, currencies, date_from, date_to, base_currency + ): + """Get all the exchange rates from 'date_from' to 'date_to'""" + content = {} + current_date = date_from + while current_date <= date_to: + url = f"{base_url}/?from={base_currency}&date={current_date.strftime('%Y-%m-%d')}" + data = self._request_data(url) + content[current_date] = self._parse_data(data, currencies) + current_date += timedelta(days=1) + return content + + def _request_data( + self, + url, + ): + try: + return requests.request("GET", url) + except Exception as e: + raise UserError( + _("Couldn't fetch data. Please contact your administrator.") + ) from e + + def _parse_data(self, data, currencies): + result = {} + html_elem = etree.fromstring(data.content, etree.HTMLParser()) + rows_elem = html_elem.xpath(".//div[@id='table-section']//tbody/tr") + for row_elem in rows_elem: + currency_code = "".join(row_elem.find(".//th").itertext()).strip() + if currency_code in currencies: + rate = float(row_elem.find("td[2]").text.replace(",", "")) + result[currency_code] = rate + return result diff --git a/currency_rate_update_xe/readme/CONFIGURE.rst b/currency_rate_update_xe/readme/CONFIGURE.rst new file mode 100644 index 00000000..d235a063 --- /dev/null +++ b/currency_rate_update_xe/readme/CONFIGURE.rst @@ -0,0 +1,9 @@ +Now you can choose the 'XE.com' service when configuring +a currency rates providers. + +#. Go to *Invoicing > Configuration > Currency Rates Providers*. +#. Create a new 'Currency Rates Providers' or edit an existing + one and you will see 'XE.com' among the available + 'Source Services' to choose. +#. If you choose 'XE.com' as a 'Source Service', the exchange rates + will be updated from that provider. diff --git a/currency_rate_update_xe/readme/CONTRIBUTORS.rst b/currency_rate_update_xe/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..0b6bee44 --- /dev/null +++ b/currency_rate_update_xe/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Tecnativa `_: + + * Ernesto Tejeda diff --git a/currency_rate_update_xe/readme/DESCRIPTION.rst b/currency_rate_update_xe/readme/DESCRIPTION.rst new file mode 100644 index 00000000..e53d94d5 --- /dev/null +++ b/currency_rate_update_xe/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This module adds `XE.com `_ currency exchange rates provider. + +Disclaimer: The rates are fetched by scraping the corresponding web page. +Being a public page, it's legal according sentences like +https://seointel.com/news/the-court-determines-that-data-scraping-is-legal-on-linkedin/ diff --git a/currency_rate_update_xe/static/description/icon.png b/currency_rate_update_xe/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3b7d5191e85ad0e1818b9b24078210e630954b57 GIT binary patch literal 6482 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 s(-N#17z_r3!C){L3 + + + + + +Currency Rate Update: XE.com + + + +
+

Currency Rate Update: XE.com

+ + +

Beta License: AGPL-3 OCA/currency Translate me on Weblate Try me on Runboat

+

This module adds XE.com currency exchange rates provider.

+

Disclaimer: The rates are fetched by scraping the corresponding web page. +Being a public page, it’s legal according sentences like +https://seointel.com/news/the-court-determines-that-data-scraping-is-legal-on-linkedin/

+

Table of contents

+ +
+

Configuration

+

Now you can choose the ‘XE.com’ service when configuring +a currency rates providers.

+
    +
  1. Go to Invoicing > Configuration > Currency Rates Providers.
  2. +
  3. Create a new ‘Currency Rates Providers’ or edit an existing +one and you will see ‘XE.com’ among the available +‘Source Services’ to choose.
  4. +
  5. If you choose ‘XE.com’ as a ‘Source Service’, the exchange rates +will be updated from that provider.
  6. +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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/currency project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/currency_rate_update_xe/tests/__init__.py b/currency_rate_update_xe/tests/__init__.py new file mode 100644 index 00000000..10fdd20f --- /dev/null +++ b/currency_rate_update_xe/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import test_currency_rate_update_xe diff --git a/currency_rate_update_xe/tests/test_currency_rate_update_xe.py b/currency_rate_update_xe/tests/test_currency_rate_update_xe.py new file mode 100644 index 00000000..8e33fcc2 --- /dev/null +++ b/currency_rate_update_xe/tests/test_currency_rate_update_xe.py @@ -0,0 +1,52 @@ +# Copyright 2023 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +from odoo import fields +from odoo.tests import common + + +class TestResCurrencyRateProviderXE(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.Company = cls.env["res.company"] + cls.CurrencyRate = cls.env["res.currency.rate"] + cls.CurrencyRateProvider = cls.env["res.currency.rate.provider"] + + cls.today = fields.Date.today() + cls.eur_currency = cls.env.ref("base.EUR") + cls.usd_currency = cls.env.ref("base.USD") + cls.company = cls.Company.create( + {"name": "Test company", "currency_id": cls.eur_currency.id} + ) + cls.env.user.company_ids += cls.company + cls.env.company = cls.company + cls.xe_provider = cls.CurrencyRateProvider.create( + { + "service": "XE", + "currency_ids": [ + (4, cls.usd_currency.id), + (4, cls.eur_currency.id), + ], + } + ) + cls.CurrencyRate.search([]).unlink() + + def test_cron(self): + self.xe_provider._scheduled_update() + rates = self.CurrencyRate.search([]) + self.assertEqual(len(rates), 1) + self.assertEqual(rates.currency_id, self.usd_currency) + + def test_wizard(self): + wizard = ( + self.env["res.currency.rate.update.wizard"] + .with_context(default_provider_ids=[(6, False, self.xe_provider.ids)]) + .create({}) + ) + wizard.action_update() + rates = self.CurrencyRate.search([]) + self.assertEqual(len(rates), 1) + self.assertEqual(rates.currency_id, self.usd_currency) From a2c37281932a990736caef80c10f99be14bf82ae Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 13 Apr 2023 18:23:32 +0000 Subject: [PATCH 2/8] [UPD] Update currency_rate_update_xe.pot --- currency_rate_update_xe/i18n/currency_rate_update_xe.pot | 2 -- 1 file changed, 2 deletions(-) diff --git a/currency_rate_update_xe/i18n/currency_rate_update_xe.pot b/currency_rate_update_xe/i18n/currency_rate_update_xe.pot index a09e3226..0bf51d7d 100644 --- a/currency_rate_update_xe/i18n/currency_rate_update_xe.pot +++ b/currency_rate_update_xe/i18n/currency_rate_update_xe.pot @@ -6,8 +6,6 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-04-11 07:38+0000\n" -"PO-Revision-Date: 2023-04-11 07:38+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" From 509e2230a38789a31890a71dca3793445939525a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 13 Apr 2023 18:27:01 +0000 Subject: [PATCH 3/8] [UPD] README.rst --- currency_rate_update_xe/README.rst | 6 +++--- currency_rate_update_xe/static/description/index.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/currency_rate_update_xe/README.rst b/currency_rate_update_xe/README.rst index ebcdb045..d09ff09c 100644 --- a/currency_rate_update_xe/README.rst +++ b/currency_rate_update_xe/README.rst @@ -19,9 +19,9 @@ Currency Rate Update: XE.com .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png :target: https://translation.odoo-community.org/projects/currency-15-0/currency-15-0-currency_rate_update_xe :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/currency&target_branch=15.0 - :alt: Try me on Runboat +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/259/15.0 + :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| diff --git a/currency_rate_update_xe/static/description/index.html b/currency_rate_update_xe/static/description/index.html index b144583e..1cbe1ab7 100644 --- a/currency_rate_update_xe/static/description/index.html +++ b/currency_rate_update_xe/static/description/index.html @@ -3,7 +3,7 @@ - + Currency Rate Update: XE.com