diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f67bb1410..9b5fc18bc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -140,7 +140,7 @@ repos: - --settings=. exclude: /__init__\.py$ - repo: https://github.com/acsone/setuptools-odoo - rev: 3.1.8 + rev: 3.3.2 hooks: - id: setuptools-odoo-make-default - id: setuptools-odoo-get-requirements diff --git a/currency_rate_update_xe/__manifest__.py b/currency_rate_update_xe/__manifest__.py index 821f85fd2..0e64a616b 100644 --- a/currency_rate_update_xe/__manifest__.py +++ b/currency_rate_update_xe/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Currency Rate Update: XE.com", - "version": "14.0.1.0.0", + "version": "14.0.1.0.1", "category": "Financial Management/Configuration", "summary": "Update exchange rates using XE.com", "author": "Tecnativa, Odoo Community Association (OCA)", 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 index b18a2abc2..008529973 100644 --- a/currency_rate_update_xe/models/res_currency_rate_provider_XE.py +++ b/currency_rate_update_xe/models/res_currency_rate_provider_XE.py @@ -241,8 +241,16 @@ def _get_historical_rate( """Get all the exchange rates from 'date_from' to 'date_to'""" content = {} current_date = date_from + today = date.today() while current_date <= date_to: - url = f"{base_url}/?from={base_currency}&date={current_date.strftime('%Y-%m-%d')}" + if current_date >= today: + # XE.com returns HTTP 404 for ``?date=YYYY-MM-DD`` when the + # requested date is today or in the future; fall back to the + # latest endpoint (same URL as ``_get_latest_rate``). + url = f"{base_url}/?from={base_currency}" + else: + day = current_date.strftime("%Y-%m-%d") + url = f"{base_url}/?from={base_currency}&date={day}" data = self._request_data(url) content[current_date] = self._parse_data(data, currencies) current_date += timedelta(days=1) @@ -253,7 +261,15 @@ def _request_data( url, ): try: - return requests.request("GET", url) + # XE.com returns HTTP 403 to requests without a User-Agent header. + response = requests.request( + "GET", + url, + timeout=10, + headers={"User-Agent": "Mozilla/5.0"}, + ) + response.raise_for_status() + return response except Exception as e: raise UserError( _("Couldn't fetch data. Please contact your administrator.") 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 index 04535a7e0..21e7f98f3 100644 --- a/currency_rate_update_xe/tests/test_currency_rate_update_xe.py +++ b/currency_rate_update_xe/tests/test_currency_rate_update_xe.py @@ -1,10 +1,44 @@ # Copyright 2023 Tecnativa - Ernesto Tejeda # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from unittest import mock + +import requests +from dateutil.relativedelta import relativedelta from odoo import fields +from odoo.exceptions import UserError from odoo.tests import common +from ..models import res_currency_rate_provider_XE as xe_module + +_PROVIDER = ( + "odoo.addons.currency_rate_update_xe.models" + ".res_currency_rate_provider_XE.ResCurrencyRateProviderXE" +) +_REQUEST_DATA = _PROVIDER + "._request_data" + +# Minimal XE.com currency-table HTML matching the provider's xpath +# (//div[@id='table-section']//tbody/tr ; th = currency code ; td[2] = rate). +_XE_HTML = b"""
+| USD | US Dollar | 0.920000 |
|---|---|---|
| GBP | British Pound | 1.170000 |