diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py index 9255b0feaf..2a8042f4f7 100644 --- a/InvenTree/InvenTree/api_version.py +++ b/InvenTree/InvenTree/api_version.py @@ -2,11 +2,15 @@ # InvenTree API version -INVENTREE_API_VERSION = 92 +INVENTREE_API_VERSION = 93 """ Increment this API version number whenever there is a significant change to the API that any clients need to know about +v93 -> 2023-02-03 : https://github.com/inventree/InvenTree/pull/4300 + - Adds extra information to the currency exchange endpoint + - Adds API endpoint for manually updating exchange rates + v92 -> 2023-02-02 : https://github.com/inventree/InvenTree/pull/4293 - Adds API endpoint for currency exchange information diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index d63e4022f4..bf3e36c8e3 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -31,8 +31,8 @@ from stock.urls import stock_urls from users.api import user_urls from .api import InfoView, NotFoundView -from .views import (AboutView, AppearanceSelectView, CurrencyRefreshView, - CustomConnectionsView, CustomEmailView, CustomLoginView, +from .views import (AboutView, AppearanceSelectView, CustomConnectionsView, + CustomEmailView, CustomLoginView, CustomPasswordResetFromKeyView, CustomSessionDeleteOtherView, CustomSessionDeleteView, CustomTwoFactorRemove, DatabaseStatsView, DynamicJsView, @@ -73,7 +73,6 @@ settings_urls = [ re_path(r'^i18n/?', include('django.conf.urls.i18n')), re_path(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'), - re_path(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'), # Catch any other urls re_path(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'), diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py index 13f098ee7d..57bed19275 100644 --- a/InvenTree/InvenTree/views.py +++ b/InvenTree/InvenTree/views.py @@ -652,20 +652,6 @@ class CustomLoginView(LoginView): return super().get(request, *args, **kwargs) -class CurrencyRefreshView(RedirectView): - """POST endpoint to refresh / update exchange rates.""" - - url = reverse_lazy("settings-currencies") - - def post(self, request, *args, **kwargs): - """On a POST request we will attempt to refresh the exchange rates.""" - from InvenTree.tasks import offload_task, update_exchange_rates - - offload_task(update_exchange_rates, force_sync=True) - - return redirect(reverse_lazy('settings')) - - class AppearanceSelectView(RedirectView): """View for selecting a color theme.""" diff --git a/InvenTree/common/api.py b/InvenTree/common/api.py index e717ed4c68..82fae54cd2 100644 --- a/InvenTree/common/api.py +++ b/InvenTree/common/api.py @@ -9,7 +9,7 @@ from django.views.decorators.csrf import csrf_exempt from django_filters.rest_framework import DjangoFilterBackend from django_q.tasks import async_task -from djmoney.contrib.exchange.models import Rate +from djmoney.contrib.exchange.models import ExchangeBackend, Rate from rest_framework import filters, permissions, serializers from rest_framework.exceptions import NotAcceptable, NotFound from rest_framework.permissions import IsAdminUser @@ -104,10 +104,7 @@ class WebhookView(CsrfExemptMixin, APIView): class CurrencyExchangeView(APIView): - """API endpoint for displaying currency information - - TODO: Add a POST hook to refresh / update the currency exchange data - """ + """API endpoint for displaying currency information""" permission_classes = [ permissions.IsAuthenticated, @@ -122,9 +119,17 @@ class CurrencyExchangeView(APIView): except Exception: rates = [] + # Information on last update + try: + backend = ExchangeBackend.objects.get(name='InvenTreeExchange') + updated = backend.last_update + except Exception: + updated = None + response = { 'base_currency': common.models.InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY', 'USD'), - 'exchange_rates': {} + 'exchange_rates': {}, + 'updated': updated, } for rate in rates: @@ -133,6 +138,29 @@ class CurrencyExchangeView(APIView): return Response(response) +class CurrencyRefreshView(APIView): + """API endpoint for manually refreshing currency exchange rates. + + User must be a 'staff' user to access this endpoint + """ + + permission_classes = [ + permissions.IsAuthenticated, + permissions.IsAdminUser, + ] + + def post(self, request, *args, **kwargs): + """Performing a POST request will update currency exchange rates""" + + from InvenTree.tasks import update_exchange_rates + + update_exchange_rates + + return Response({ + 'success': 'Exchange rates updated', + }) + + class SettingsList(ListAPI): """Generic ListView for settings. @@ -452,6 +480,7 @@ common_api_urls = [ # Currencies re_path(r'^currency/', include([ re_path(r'^exchange/', CurrencyExchangeView.as_view(), name='api-currency-exchange'), + re_path(r'^refresh/', CurrencyRefreshView.as_view(), name='api-currency-refresh'), ])), # Notifications diff --git a/InvenTree/templates/InvenTree/settings/pricing.html b/InvenTree/templates/InvenTree/settings/pricing.html index fc9bb88f77..bbcaf1a0ba 100644 --- a/InvenTree/templates/InvenTree/settings/pricing.html +++ b/InvenTree/templates/InvenTree/settings/pricing.html @@ -11,6 +11,7 @@