mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Simplify exhange rate backend
This commit is contained in:
parent
62320e46d5
commit
af1904b6e4
@ -1,120 +1,29 @@
|
||||
from django.conf import settings as inventree_settings
|
||||
|
||||
from djmoney.contrib.exchange.backends.base import BaseExchangeBackend
|
||||
from djmoney.contrib.exchange.models import Rate
|
||||
|
||||
from common.models import InvenTreeSetting
|
||||
from djmoney.contrib.exchange.backends.base import SimpleExchangeBackend
|
||||
|
||||
|
||||
def get_exchange_rate_backend():
|
||||
""" Return the exchange rate backend set by user """
|
||||
|
||||
custom = InvenTreeSetting.get_setting('CUSTOM_EXCHANGE_RATES', False)
|
||||
|
||||
if custom:
|
||||
return InvenTreeManualExchangeBackend()
|
||||
else:
|
||||
return ExchangeRateHostBackend()
|
||||
|
||||
|
||||
class InvenTreeManualExchangeBackend(BaseExchangeBackend):
|
||||
class InvenTreeExchange(SimpleExchangeBackend):
|
||||
"""
|
||||
Backend for manually updating currency exchange rates
|
||||
Backend for automatically updating currency exchange rates.
|
||||
|
||||
See the documentation for django-money: https://github.com/django-money/django-money
|
||||
|
||||
Specifically: https://github.com/django-money/django-money/tree/master/djmoney/contrib/exchange/backends
|
||||
Uses the exchangerate.host service API
|
||||
"""
|
||||
|
||||
name = 'inventree'
|
||||
url = None
|
||||
custom_rates = True
|
||||
base_currency = None
|
||||
currencies = []
|
||||
|
||||
def update_default_currency(self):
|
||||
""" Update to base currency """
|
||||
|
||||
self.base_currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY', 'USD')
|
||||
|
||||
def __init__(self, url=None):
|
||||
""" Overrides init to update url, base currency and currencies """
|
||||
|
||||
self.url = url
|
||||
|
||||
self.update_default_currency()
|
||||
|
||||
# Update name
|
||||
self.name = self.name + '-' + self.base_currency.lower()
|
||||
|
||||
self.currencies = inventree_settings.CURRENCIES
|
||||
|
||||
super().__init__()
|
||||
|
||||
def get_rates(self, **kwargs):
|
||||
""" Returns a mapping <currency>: <rate> """
|
||||
|
||||
return kwargs.get('rates', {})
|
||||
|
||||
def get_stored_rates(self):
|
||||
""" Returns stored rate for specified backend and base currency """
|
||||
|
||||
stored_rates = {}
|
||||
|
||||
stored_rates_obj = Rate.objects.all().prefetch_related('backend')
|
||||
|
||||
for rate in stored_rates_obj:
|
||||
# Find match for backend and base currency
|
||||
if rate.backend.name == self.name and rate.backend.base_currency == self.base_currency:
|
||||
# print(f'{rate.currency} | {rate.value} | {rate.backend} | {rate.backend.base_currency}')
|
||||
stored_rates[rate.currency] = rate.value
|
||||
|
||||
return stored_rates
|
||||
|
||||
|
||||
class ExchangeRateHostBackend(InvenTreeManualExchangeBackend):
|
||||
"""
|
||||
Backend for https://exchangerate.host/
|
||||
"""
|
||||
|
||||
name = "exchangerate.host"
|
||||
name = "InvenTreeExchange"
|
||||
|
||||
def __init__(self):
|
||||
self.url = "https://api.exchangerate.host/latest"
|
||||
|
||||
self.custom_rates = False
|
||||
|
||||
super().__init__(url=self.url)
|
||||
super().__init__()
|
||||
|
||||
def get_params(self):
|
||||
# No API key is required
|
||||
return {}
|
||||
return {
|
||||
}
|
||||
|
||||
def update_rates(self, base_currency=None):
|
||||
""" Override update_rates method using currencies found in the settings
|
||||
"""
|
||||
def update_rates(self, base_currency=inventree_settings.BASE_CURRENCY):
|
||||
|
||||
if base_currency:
|
||||
self.base_currency = base_currency
|
||||
else:
|
||||
self.update_default_currency()
|
||||
|
||||
symbols = ','.join(self.currencies)
|
||||
symbols = ','.join(inventree_settings.CURRENCIES)
|
||||
|
||||
super().update_rates(base_currency=self.base_currency, symbols=symbols)
|
||||
|
||||
def get_rates(self, **params):
|
||||
""" Returns a mapping <currency>: <rate> """
|
||||
|
||||
# Set base currency
|
||||
params.update(base=self.base_currency)
|
||||
|
||||
response = self.get_response(**params)
|
||||
|
||||
try:
|
||||
return self.parse_json(response)['rates']
|
||||
except KeyError:
|
||||
# API response did not contain any rate
|
||||
pass
|
||||
|
||||
return {}
|
||||
super().update_rates(base=base_currency, symbols=symbols)
|
||||
|
@ -19,6 +19,8 @@ import shutil
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
import moneyed
|
||||
|
||||
import yaml
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@ -513,11 +515,20 @@ CURRENCIES = CONFIG.get(
|
||||
],
|
||||
)
|
||||
|
||||
DEFAULT_CURRENCY = get_setting(
|
||||
'INVENTREE_DEFAULT_CURRENCY',
|
||||
CONFIG.get('default_currency', 'USD')
|
||||
# Check that each provided currency is supported
|
||||
for currency in CURRENCIES:
|
||||
if currency not in moneyed.CURRENCIES:
|
||||
print(f"Currency code '{currency}' is not supported")
|
||||
sys.exit(1)
|
||||
|
||||
BASE_CURRENCY = get_setting(
|
||||
'INVENTREE_BASE_CURRENCY',
|
||||
CONFIG.get('base_currency', 'USD')
|
||||
)
|
||||
|
||||
# Custom currency exchange backend
|
||||
EXCHANGE_BACKEND = 'InvenTree.exchange.InvenTreeExchange'
|
||||
|
||||
# Extract email settings from the config file
|
||||
email_config = CONFIG.get('email', {})
|
||||
|
||||
|
@ -167,16 +167,16 @@ def update_exchange_rates():
|
||||
"""
|
||||
|
||||
try:
|
||||
import common.models
|
||||
from InvenTree.exchange import ExchangeRateHostBackend
|
||||
from InvenTree.exchange import InvenTreeExchange
|
||||
from django.conf import settings
|
||||
except AppRegistryNotReady:
|
||||
# Apps not yet loaded!
|
||||
return
|
||||
|
||||
backend = ExchangeRateHostBackend()
|
||||
backend = InvenTreeExchange()
|
||||
print(f"Updating exchange rates from {backend.url}")
|
||||
|
||||
base = common.models.InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
||||
base = settings.BASE_CURRENCY
|
||||
|
||||
print(f"Using base currency '{base}'")
|
||||
|
||||
|
@ -41,7 +41,6 @@ from .views import IndexView, SearchView, DatabaseStatsView
|
||||
from .views import SettingsView, EditUserView, SetPasswordView
|
||||
from .views import AppearanceSelectView, SettingCategorySelectView
|
||||
from .views import DynamicJsView
|
||||
from .views import CurrencySettingsView
|
||||
|
||||
from common.views import SettingEdit
|
||||
|
||||
@ -91,7 +90,7 @@ settings_urls = [
|
||||
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'^sales-order/?', SettingsView.as_view(template_name='InvenTree/settings/so.html'), name='settings-so'),
|
||||
url(r'^currencies/?', CurrencySettingsView.as_view(), name='settings-currencies'),
|
||||
url(r'^currencies/?', SettingsView.as_view(template_name='InvenTree/settings/currencies.html'), name='settings-currencies'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/edit/', SettingEdit.as_view(), name='setting-edit'),
|
||||
|
||||
|
@ -13,6 +13,8 @@ from djmoney.forms.fields import MoneyField
|
||||
from InvenTree.forms import HelperForm
|
||||
from InvenTree.helpers import clean_decimal
|
||||
|
||||
from common.settings import currency_code_default
|
||||
|
||||
from .files import FileManager
|
||||
from .models import InvenTreeSetting
|
||||
|
||||
@ -182,7 +184,7 @@ class MatchItem(forms.Form):
|
||||
if 'price' in col_guess.lower():
|
||||
self.fields[field_name] = MoneyField(
|
||||
label=_(col_guess),
|
||||
default_currency=InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY'),
|
||||
default_currency=currency_code_default(),
|
||||
decimal_places=5,
|
||||
max_digits=19,
|
||||
required=False,
|
||||
|
@ -19,6 +19,8 @@ from djmoney.models.fields import MoneyField
|
||||
from djmoney.contrib.exchange.models import convert_money
|
||||
from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
|
||||
from common.settings import currency_code_default
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.validators import MinValueValidator, URLValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
@ -80,20 +82,6 @@ class InvenTreeSetting(models.Model):
|
||||
'default': '',
|
||||
},
|
||||
|
||||
'INVENTREE_DEFAULT_CURRENCY': {
|
||||
'name': _('Default Currency'),
|
||||
'description': _('Default currency'),
|
||||
'default': 'USD',
|
||||
'choices': djmoney.settings.CURRENCY_CHOICES,
|
||||
},
|
||||
|
||||
'CUSTOM_EXCHANGE_RATES': {
|
||||
'name': _('Custom Exchange Rates'),
|
||||
'description': _('Enable custom exchange rates'),
|
||||
'validator': bool,
|
||||
'default': False,
|
||||
},
|
||||
|
||||
'INVENTREE_DOWNLOAD_FROM_URL': {
|
||||
'name': _('Download from URL'),
|
||||
'description': _('Allow download of remote images and files from external URL'),
|
||||
@ -766,7 +754,7 @@ def get_price(instance, quantity, moq=True, multiples=True, currency=None):
|
||||
|
||||
if currency is None:
|
||||
# Default currency selection
|
||||
currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
||||
currency = currency_code_default()
|
||||
|
||||
pb_min = None
|
||||
for pb in instance.price_breaks.all():
|
||||
|
@ -7,7 +7,8 @@ from __future__ import unicode_literals
|
||||
|
||||
from moneyed import CURRENCIES
|
||||
|
||||
from common.models import InvenTreeSetting
|
||||
import common.models
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def currency_code_default():
|
||||
@ -15,7 +16,7 @@ def currency_code_default():
|
||||
Returns the default currency code (or USD if not specified)
|
||||
"""
|
||||
|
||||
code = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
||||
code = settings.BASE_CURRENCY
|
||||
|
||||
if code not in CURRENCIES:
|
||||
code = 'USD'
|
||||
@ -28,4 +29,4 @@ def stock_expiry_enabled():
|
||||
Returns True if the stock expiry feature is enabled
|
||||
"""
|
||||
|
||||
return InvenTreeSetting.get_setting('STOCK_ENABLE_EXPIRY')
|
||||
return common.models.InvenTreeSetting.get_setting('STOCK_ENABLE_EXPIRY')
|
||||
|
@ -52,6 +52,9 @@ language: en-us
|
||||
# Use the environment variable INVENTREE_TIMEZONE
|
||||
timezone: UTC
|
||||
|
||||
# Base currency code
|
||||
base_currency: USD
|
||||
|
||||
# List of currencies supported by default.
|
||||
# Add other currencies here to allow use in InvenTree
|
||||
currencies:
|
||||
|
@ -2675,7 +2675,7 @@ class PartSalePriceBreakCreate(AjaxCreateView):
|
||||
|
||||
initials['part'] = self.get_part()
|
||||
|
||||
default_currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
||||
default_currency = settings.BASE_CURRENCY
|
||||
currency = CURRENCIES.get(default_currency, None)
|
||||
|
||||
if currency is not None:
|
||||
|
@ -15,6 +15,9 @@
|
||||
<li {% if tab == 'global' %} class='active' {% endif %}>
|
||||
<a href='{% url "settings-global" %}'><span class='fas fa-globe'></span> {% trans "Global" %}</a>
|
||||
</li>
|
||||
<li {% if tab == 'currencies' %} class='active'{% endif %}>
|
||||
<a href="{% url 'settings-currencies' %}"><span class='fas fa-dollar-sign'></span> {% trans "Currencies" %}</a>
|
||||
</li>
|
||||
<li {% if tab == 'report' %} class='active' {% endif %}>
|
||||
<a href='{% url "settings-report" %}'><span class='fas fa-file-pdf'></span> {% trans "Report" %}</a>
|
||||
</li>
|
||||
@ -36,8 +39,5 @@
|
||||
<li {% if tab == 'so' %} class='active'{% endif %}>
|
||||
<a href="{% url 'settings-so' %}"><span class='fas fa-truck'></span> {% trans "Sales Orders" %}</a>
|
||||
</li>
|
||||
<li {% if tab == 'currencies' %} class='active'{% endif %}>
|
||||
<a href="{% url 'settings-currencies' %}"><span class='fas fa-dollar-sign'></span> {% trans "Currencies" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user