mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-15 03:25:42 +00:00
Remove common_currency model entirely
- A lot of views / pages / etc needed to be updated too - Now uses django-money fields entirely - Create a manual rate exchange backend (needs more work!)
This commit is contained in:
@ -5,11 +5,7 @@ from django.contrib import admin
|
||||
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
|
||||
from .models import Currency, InvenTreeSetting
|
||||
|
||||
|
||||
class CurrencyAdmin(ImportExportModelAdmin):
|
||||
list_display = ('symbol', 'suffix', 'description', 'value', 'base')
|
||||
from .models import InvenTreeSetting
|
||||
|
||||
|
||||
class SettingsAdmin(ImportExportModelAdmin):
|
||||
@ -17,5 +13,4 @@ class SettingsAdmin(ImportExportModelAdmin):
|
||||
list_display = ('key', 'value')
|
||||
|
||||
|
||||
admin.site.register(Currency, CurrencyAdmin)
|
||||
admin.site.register(InvenTreeSetting, SettingsAdmin)
|
||||
|
@ -5,35 +5,5 @@ Provides a JSON API for common components.
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from rest_framework import permissions, generics, filters
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from .models import Currency
|
||||
from .serializers import CurrencySerializer
|
||||
|
||||
|
||||
class CurrencyList(generics.ListCreateAPIView):
|
||||
""" API endpoint for accessing a list of Currency objects.
|
||||
|
||||
- GET: Return a list of Currencies
|
||||
- POST: Create a new currency
|
||||
"""
|
||||
|
||||
queryset = Currency.objects.all()
|
||||
serializer_class = CurrencySerializer
|
||||
|
||||
permission_classes = [
|
||||
permissions.IsAuthenticated,
|
||||
]
|
||||
|
||||
filter_backends = [
|
||||
filters.OrderingFilter,
|
||||
]
|
||||
|
||||
ordering_fields = ['suffix', 'value']
|
||||
|
||||
|
||||
common_api_urls = [
|
||||
url(r'^currency/?$', CurrencyList.as_view(), name='api-currency-list'),
|
||||
]
|
||||
|
@ -7,21 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from InvenTree.forms import HelperForm
|
||||
|
||||
from .models import Currency, InvenTreeSetting
|
||||
|
||||
|
||||
class CurrencyEditForm(HelperForm):
|
||||
""" Form for creating / editing a currency object """
|
||||
|
||||
class Meta:
|
||||
model = Currency
|
||||
fields = [
|
||||
'symbol',
|
||||
'suffix',
|
||||
'description',
|
||||
'value',
|
||||
'base'
|
||||
]
|
||||
from .models import InvenTreeSetting
|
||||
|
||||
|
||||
class SettingEditForm(HelperForm):
|
||||
|
18
InvenTree/common/migrations/0009_delete_currency.py
Normal file
18
InvenTree/common/migrations/0009_delete_currency.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.0.7 on 2020-11-10 11:40
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('company', '0027_remove_supplierpricebreak_currency'),
|
||||
('part', '0057_remove_partsellpricebreak_currency'),
|
||||
('common', '0008_remove_inventreesetting_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='Currency',
|
||||
),
|
||||
]
|
@ -7,16 +7,18 @@ These models are 'generic' and do not fit a particular business logic object.
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import decimal
|
||||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
import djmoney.settings
|
||||
from djmoney.models.fields import MoneyField
|
||||
from djmoney.money import Money
|
||||
from djmoney.contrib.exchange.models import convert_money
|
||||
from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||
from django.core.validators import MinValueValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
import InvenTree.helpers
|
||||
@ -455,74 +457,6 @@ class InvenTreeSetting(models.Model):
|
||||
return InvenTree.helpers.str2bool(self.value)
|
||||
|
||||
|
||||
class Currency(models.Model):
|
||||
"""
|
||||
A Currency object represents a particular unit of currency.
|
||||
Each Currency has a scaling factor which relates it to the base currency.
|
||||
There must be one (and only one) currency which is selected as the base currency,
|
||||
and each other currency is calculated relative to it.
|
||||
|
||||
Attributes:
|
||||
symbol: Currency symbol e.g. $
|
||||
suffix: Currency suffix e.g. AUD
|
||||
description: Long-form description e.g. "Australian Dollars"
|
||||
value: The value of this currency compared to the base currency.
|
||||
base: True if this currency is the base currency
|
||||
|
||||
"""
|
||||
|
||||
symbol = models.CharField(max_length=10, blank=False, unique=False, help_text=_('Currency Symbol e.g. $'))
|
||||
|
||||
suffix = models.CharField(max_length=10, blank=False, unique=True, help_text=_('Currency Suffix e.g. AUD'))
|
||||
|
||||
description = models.CharField(max_length=100, blank=False, help_text=_('Currency Description'))
|
||||
|
||||
value = models.DecimalField(default=1.0, max_digits=10, decimal_places=5, validators=[MinValueValidator(0.00001), MaxValueValidator(100000)], help_text=_('Currency Value'))
|
||||
|
||||
base = models.BooleanField(default=False, help_text=_('Use this currency as the base currency'))
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'Currencies'
|
||||
|
||||
def __str__(self):
|
||||
""" Format string for currency representation """
|
||||
s = "{sym} {suf} - {desc}".format(
|
||||
sym=self.symbol,
|
||||
suf=self.suffix,
|
||||
desc=self.description
|
||||
)
|
||||
|
||||
if self.base:
|
||||
s += " (Base)"
|
||||
|
||||
else:
|
||||
s += " = {v}".format(v=self.value)
|
||||
|
||||
return s
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
""" Validate the model before saving
|
||||
|
||||
- Ensure that there is only one base currency!
|
||||
"""
|
||||
|
||||
# If this currency is set as the base currency, ensure no others are
|
||||
if self.base:
|
||||
for cur in Currency.objects.filter(base=True).exclude(pk=self.pk):
|
||||
cur.base = False
|
||||
cur.save()
|
||||
|
||||
# If there are no currencies set as the base currency, set this as base
|
||||
if not Currency.objects.exclude(pk=self.pk).filter(base=True).exists():
|
||||
self.base = True
|
||||
|
||||
# If this is the base currency, ensure value is set to unity
|
||||
if self.base:
|
||||
self.value = 1.0
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class PriceBreak(models.Model):
|
||||
"""
|
||||
Represents a PriceBreak model
|
||||
@ -533,10 +467,6 @@ class PriceBreak(models.Model):
|
||||
|
||||
quantity = InvenTree.fields.RoundingDecimalField(max_digits=15, decimal_places=5, default=1, validators=[MinValueValidator(1)])
|
||||
|
||||
cost = InvenTree.fields.RoundingDecimalField(max_digits=10, decimal_places=5, validators=[MinValueValidator(0)])
|
||||
|
||||
currency = models.ForeignKey(Currency, blank=True, null=True, on_delete=models.SET_NULL)
|
||||
|
||||
price = MoneyField(
|
||||
max_digits=19,
|
||||
decimal_places=4,
|
||||
@ -546,26 +476,21 @@ class PriceBreak(models.Model):
|
||||
help_text=_('Unit price at specified quantity'),
|
||||
)
|
||||
|
||||
@property
|
||||
def symbol(self):
|
||||
return self.currency.symbol if self.currency else ''
|
||||
|
||||
@property
|
||||
def suffix(self):
|
||||
return self.currency.suffix if self.currency else ''
|
||||
|
||||
@property
|
||||
def converted_cost(self):
|
||||
def convert_to(self, currency_code):
|
||||
"""
|
||||
Return the cost of this price break, converted to the base currency
|
||||
Convert the unit-price at this price break to the specified currency code.
|
||||
|
||||
Args:
|
||||
currency_code - The currency code to convert to (e.g "USD" or "AUD")
|
||||
"""
|
||||
|
||||
scaler = decimal.Decimal(1.0)
|
||||
try:
|
||||
converted = convert_money(self.price, currency_code)
|
||||
except MissingRate:
|
||||
print(f"WARNING: No currency conversion rate available for {self.price_currency} -> {currency_code}")
|
||||
return self.price.amount
|
||||
|
||||
if self.currency:
|
||||
scaler = self.currency.value
|
||||
|
||||
return self.cost * scaler
|
||||
return converted.amount
|
||||
|
||||
|
||||
class ColorTheme(models.Model):
|
||||
|
@ -1,22 +1,3 @@
|
||||
"""
|
||||
JSON serializers for common components
|
||||
"""
|
||||
|
||||
from .models import Currency
|
||||
|
||||
from InvenTree.serializers import InvenTreeModelSerializer
|
||||
|
||||
|
||||
class CurrencySerializer(InvenTreeModelSerializer):
|
||||
""" Serializer for Currency object """
|
||||
|
||||
class Meta:
|
||||
model = Currency
|
||||
fields = [
|
||||
'pk',
|
||||
'symbol',
|
||||
'suffix',
|
||||
'description',
|
||||
'value',
|
||||
'base'
|
||||
]
|
||||
|
@ -4,7 +4,7 @@ from __future__ import unicode_literals
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from .models import Currency, InvenTreeSetting
|
||||
from .models import InvenTreeSetting
|
||||
|
||||
|
||||
class CurrencyTest(TestCase):
|
||||
|
@ -2,17 +2,5 @@
|
||||
URL lookup for common views
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
|
||||
from . import views
|
||||
|
||||
currency_urls = [
|
||||
url(r'^new/', views.CurrencyCreate.as_view(), name='currency-create'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/edit/', views.CurrencyEdit.as_view(), name='currency-edit'),
|
||||
url(r'^(?P<pk>\d+)/delete/', views.CurrencyDelete.as_view(), name='currency-delete'),
|
||||
]
|
||||
|
||||
common_urls = [
|
||||
url(r'currency/', include(currency_urls)),
|
||||
]
|
||||
|
@ -8,37 +8,13 @@ from __future__ import unicode_literals
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.forms import CheckboxInput, Select
|
||||
|
||||
from InvenTree.views import AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
||||
from InvenTree.views import AjaxUpdateView
|
||||
from InvenTree.helpers import str2bool
|
||||
|
||||
from . import models
|
||||
from . import forms
|
||||
|
||||
|
||||
class CurrencyCreate(AjaxCreateView):
|
||||
""" View for creating a new Currency object """
|
||||
|
||||
model = models.Currency
|
||||
form_class = forms.CurrencyEditForm
|
||||
ajax_form_title = _('Create new Currency')
|
||||
|
||||
|
||||
class CurrencyEdit(AjaxUpdateView):
|
||||
""" View for editing an existing Currency object """
|
||||
|
||||
model = models.Currency
|
||||
form_class = forms.CurrencyEditForm
|
||||
ajax_form_title = _('Edit Currency')
|
||||
|
||||
|
||||
class CurrencyDelete(AjaxDeleteView):
|
||||
""" View for deleting an existing Currency object """
|
||||
|
||||
model = models.Currency
|
||||
ajax_form_title = _('Delete Currency')
|
||||
ajax_template_name = "common/delete_currency.html"
|
||||
|
||||
|
||||
class SettingEdit(AjaxUpdateView):
|
||||
"""
|
||||
View for editing an InvenTree key:value settings object,
|
||||
|
Reference in New Issue
Block a user