Added exchange rates form

This commit is contained in:
eeintech 2021-05-20 09:49:56 -04:00
parent 6d5b2d3227
commit bed6a7e49c
6 changed files with 125 additions and 43 deletions

View File

@ -1,12 +1,21 @@
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings as inventree_settings from django.conf import settings as inventree_settings
from djmoney import settings as djmoney_settings from djmoney import settings as djmoney_settings
from djmoney.contrib.exchange.backends.base import BaseExchangeBackend from djmoney.contrib.exchange.backends.base import BaseExchangeBackend
from djmoney.contrib.exchange.backends import FixerBackend
from common.models import InvenTreeSetting from common.models import InvenTreeSetting
def get_exchange_rate_backend():
""" Return the exchange rate backend set by user """
if 'InvenTreeManualExchangeBackend' in inventree_settings.EXCHANGE_BACKEND:
return InvenTreeManualExchangeBackend()
else:
return InvenTreeFixerExchangeBackend()
class InvenTreeManualExchangeBackend(BaseExchangeBackend): class InvenTreeManualExchangeBackend(BaseExchangeBackend):
""" """
Backend for manually updating currency exchange rates Backend for manually updating currency exchange rates
@ -16,22 +25,39 @@ class InvenTreeManualExchangeBackend(BaseExchangeBackend):
Specifically: https://github.com/django-money/django-money/tree/master/djmoney/contrib/exchange/backends Specifically: https://github.com/django-money/django-money/tree/master/djmoney/contrib/exchange/backends
""" """
name = "inventree" name = 'inventree'
url = None url = None
default_currency = None
currencies = []
def update_default_currency(self):
self.default_currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY', inventree_settings.BASE_CURRENCY)
def __init__(self, url=None):
self.url = url
self.update_default_currency()
self.currencies = inventree_settings.CURRENCIES
super().__init__()
def get_rates(self, **kwargs): def get_rates(self, **kwargs):
""" """ Returns a mapping <currency>: <rate> """
Do not get any rates...
"""
return {} return {}
class InvenTreeFixerExchangeBackend(FixerBackend): class InvenTreeFixerExchangeBackend(InvenTreeManualExchangeBackend):
""" """
Backend for updating currency exchange rates using Fixer.IO API Backend for updating currency exchange rates using Fixer.IO API
""" """
name = 'fixer.io'
access_key = None
def get_api_key(self): def get_api_key(self):
""" Get API key from global settings """ """ Get API key from global settings """
@ -48,18 +74,17 @@ class InvenTreeFixerExchangeBackend(FixerBackend):
fixer_api_key = self.get_api_key() fixer_api_key = self.get_api_key()
super().__init__(url=djmoney_settings.FIXER_URL, access_key=fixer_api_key) if fixer_api_key is None:
raise ImproperlyConfigured("fixer.io API key is needed to use InvenTreeFixerExchangeBackend")
self.access_key = fixer_api_key
super().__init__(url=djmoney_settings.FIXER_URL)
def update_rates(self): def update_rates(self):
""" Override update_rates method using currencies found in the settings """ """ Override update_rates method using currencies found in the settings
"""
currencies = ','.join(inventree_settings.CURRENCIES) symbols = ','.join(self.currencies)
base = inventree_settings.BASE_CURRENCY super().update_rates(base_currency=self.base_currency, symbols=symbols)
super().update_rates(base_currency=base, symbols=currencies)
def get_rates(self, **kwargs):
""" Returns a mapping <currency>: <rate> """
return {}

View File

@ -7,12 +7,15 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django import forms from django import forms
from django.contrib.auth.models import User
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field from crispy_forms.layout import Layout, Field
from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton, Div from crispy_forms.bootstrap import PrependedText, AppendedText, PrependedAppendedText, StrictButton, Div
from django.contrib.auth.models import User
from common.models import ColorTheme from common.models import ColorTheme
from part.models import PartCategory from part.models import PartCategory
from .exchange import InvenTreeManualExchangeBackend
class HelperForm(forms.ModelForm): class HelperForm(forms.ModelForm):
@ -236,3 +239,34 @@ class SettingCategorySelectForm(forms.ModelForm):
css_class='row', css_class='row',
), ),
) )
class SettingExchangeRatesForm(forms.Form):
""" Form for displaying and setting currency exchange rates manually """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
exchange_rate_backend = InvenTreeManualExchangeBackend()
# Update default currency (in case it has changed)
exchange_rate_backend.update_default_currency()
for currency in exchange_rate_backend.currencies:
if currency != exchange_rate_backend.default_currency:
# Set field name
field_name = currency
# Set field input box
self.fields[field_name] = forms.CharField(
label=field_name,
required=False,
widget=forms.NumberInput(attrs={
'name': field_name,
'class': 'numberinput',
'type': 'number',
'min': '0',
'step': 'any',
'value': '',
})
)

View File

@ -167,17 +167,13 @@ def update_exchange_rates():
""" """
try: try:
from .exchange import InvenTreeManualExchangeBackend, InvenTreeFixerExchangeBackend from .exchange import get_exchange_rate_backend
from django.conf import settings
except AppRegistryNotReady: except AppRegistryNotReady:
# Apps not yet loaded! # Apps not yet loaded!
return return
# Get backend # Get exchange rate backend
if 'InvenTreeManualExchangeBackend' in settings.EXCHANGE_BACKEND: backend = get_exchange_rate_backend()
backend = InvenTreeManualExchangeBackend()
else:
backend = InvenTreeFixerExchangeBackend()
# Update rates # Update rates
backend.update_rates() backend.update_rates()

View File

@ -41,7 +41,7 @@ from .views import IndexView, SearchView, DatabaseStatsView
from .views import SettingsView, EditUserView, SetPasswordView from .views import SettingsView, EditUserView, SetPasswordView
from .views import AppearanceSelectView, SettingCategorySelectView from .views import AppearanceSelectView, SettingCategorySelectView
from .views import DynamicJsView from .views import DynamicJsView
from .views import ExchangeRatesView from .views import CurrencySettingsView
from common.views import SettingEdit from common.views import SettingEdit
@ -91,8 +91,7 @@ settings_urls = [
url(r'^build/?', SettingsView.as_view(template_name='InvenTree/settings/build.html'), name='settings-build'), url(r'^build/?', SettingsView.as_view(template_name='InvenTree/settings/build.html'), name='settings-build'),
url(r'^purchase-order/?', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'), url(r'^purchase-order/?', SettingsView.as_view(template_name='InvenTree/settings/po.html'), name='settings-po'),
url(r'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'), url(r'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'),
url(r'^currencies/?', SettingsView.as_view(template_name='InvenTree/settings/currencies.html'), name='settings-currencies'), url(r'^currencies/?', CurrencySettingsView.as_view(), name='settings-currencies'),
url(r'^echange-rates/?', ExchangeRatesView.as_view(), name='refresh-exchange-rates'),
url(r'^(?P<pk>\d+)/edit/', SettingEdit.as_view(), name='setting-edit'), url(r'^(?P<pk>\d+)/edit/', SettingEdit.as_view(), name='setting-edit'),

View File

@ -26,8 +26,9 @@ from users.models import check_user_role, RuleSet
from .forms import DeleteForm, EditUserForm, SetPasswordForm from .forms import DeleteForm, EditUserForm, SetPasswordForm
from .forms import ColorThemeSelectForm, SettingCategorySelectForm from .forms import ColorThemeSelectForm, SettingCategorySelectForm
from .forms import SettingExchangeRatesForm
from .helpers import str2bool from .helpers import str2bool
from .tasks import update_exchange_rates from .exchange import get_exchange_rate_backend
from rest_framework import views from rest_framework import views
@ -911,14 +912,44 @@ class DatabaseStatsView(AjaxView):
return ctx return ctx
class ExchangeRatesView(SettingsView): class CurrencySettingsView(FormView):
form_class = SettingExchangeRatesForm
template_name = 'InvenTree/settings/currencies.html'
success_url = reverse_lazy('settings-currencies') success_url = reverse_lazy('settings-currencies')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Get exchange rate backend
exchange_rate_backend = get_exchange_rate_backend()
context['exchange_backend'] = exchange_rate_backend.name
return context
def get_form(self):
form = super().get_form()
# Get exchange rate backend
exchange_rate_backend = get_exchange_rate_backend()
if exchange_rate_backend.name == 'fixer.io':
# Disable all the fields
for field in form.fields:
form.fields[field].disabled = True
return form
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
# Get exchange rate backend
exchange_rate_backend = get_exchange_rate_backend()
# Process exchange rates # Process exchange rates
update_exchange_rates() exchange_rate_backend.update_rates()
# TODO: Update context # TODO: Update context

View File

@ -26,18 +26,15 @@
</div> </div>
</div> </div>
<table class='table table-striped table-condensed' id='exchange-rates'> <form action="{% url 'settings-currencies' %}" method="post">
</table>
<form action="{% url 'refresh-exchange-rates' %}" method="post">
{% csrf_token %} {% csrf_token %}
<button type="submit" class='btn btn-primary'>{% trans "Refresh Exchange Rates" %}</button> {% load crispy_forms_tags %}
{% crispy form %}
{% if exchange_backend == 'fixer.io' %}
<button type="submit" class='btn btn-primary'>{% trans "Refresh Exchange Rates" %}</button>
{% else %}
<button type="submit" class='btn btn-primary'>{% trans "Update Exchange Rates" %}</button>
{% endif %}
</form> </form>
{% endblock %} {% endblock %}
{% block js_ready %}
{{ block.super }}
{% comment %} TODO: Update exchange-rates table! {% endcomment %}
{% comment %} Or do it using context instead of JS? {% endcomment %}
{% endblock %}