def setup_default(self, default, default_currency, nullable): if default is None and not nullable: # Backwards compatible fix for non-nullable fields default = 0.0 if isinstance(default, string_types): try: # handle scenario where default is formatted like: # 'amount currency-code' amount, currency = default.split(' ') except ValueError: # value error would be risen if the default is # without the currency part, i.e # 'amount' amount = default currency = default_currency default = Money(Decimal(amount), Currency(code=currency)) elif isinstance(default, (float, Decimal, int)): default = Money(default, default_currency) elif isinstance(default, OldMoney): default.__class__ = Money if not (nullable and default is None) and not isinstance( default, Money): raise ValueError( 'default value must be an instance of Money, is: %s' % default) return default
def income(request): if request.method == 'POST': form = IncomeForm(request.POST) if form.is_valid(): amount = form.cleaned_data['amount'] tx_date = form.cleaned_data['date'] source = form.cleaned_data['source'] user = request.user # only save as USD, but note what the original amount was # also store original amount and flip converted to true if amount.currency != Currency('USD'): fxamount = amount converted = True amount = convert_money(amount, 'USD') Income.objects.create(amount=amount, date=tx_date, source=source, user=user, fxamount=fxamount, converted=converted) else: Income.objects.create(amount=amount, date=tx_date, source=source, user=user) return HttpResponseRedirect(reverse('record:index')) context = {'form': IncomeForm(), 'form_type': 'income'} return render(request, 'record/record.html', context=context)
def expense(request): # save new transaction information to database or load expense form if request.method == 'POST': # expense submission form = ExpenseForm(request.POST) if form.is_valid(): # save the input amount = form.cleaned_data['amount'] tx_date = form.cleaned_data['date'] cat = form.cleaned_data['category'] method = form.cleaned_data['method'] comment = form.cleaned_data['comment'] tag = form.cleaned_data['tag'] user = request.user # only save as USD, but note what the original amount was # also store original amount and flip converted to true if amount.currency != Currency('USD'): fxamount = amount converted = True comment = comment + ' *ORIGINAL [' + str(amount) + ']*' amount = convert_money(amount, 'USD') Expense.objects.create(amount=amount, date=tx_date, category=cat, method=method, comment=comment, tag=tag, user=user, fxamount=fxamount, converted=converted) else: # otherwise store as submitted Expense.objects.create(amount=amount, date=tx_date, category=cat, method=method, comment=comment, tag=tag, user=user) # change to new month, if different from current. also adds new month to navbar set_month(request, tx_date.year, tx_date.month) # load the index page return HttpResponseRedirect(reverse('record:index')) context = { 'message': f'Error. Form did not properly validate. Errors: {form.errors}', 'message_type': 'danger' } return render(request, 'record/index.html', context=context) # if not POST, load form context = {'form': ExpenseForm(), 'form_type': 'expense'} return render(request, 'record/record.html', context=context)
def setup_default(self, default, default_currency, nullable): if isinstance(default, (str, bytes)): try: # handle scenario where default is formatted like: # 'amount currency-code' amount, currency = default.split(" ") except ValueError: # value error would be risen if the default is # without the currency part, i.e # 'amount' amount = default currency = default_currency default = Money(Decimal(amount), Currency(code=currency)) elif isinstance(default, (float, Decimal, int)): default = Money(default, default_currency) elif isinstance(default, OldMoney): default.__class__ = Money if default is not None and not isinstance(default, Money): raise ValueError("default value must be an instance of Money, is: %s" % default) return default
from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.models import _get_rate, convert_money, get_rate from djmoney.money import Currency, Money pytestmark = pytest.mark.django_db @pytest.mark.parametrize( "source, target, expected, queries", ( ("USD", "USD", 1, 0), ("USD", "EUR", 2, 1), ("EUR", "USD", Decimal("0.5"), 1), (Currency("USD"), "USD", 1, 0), ("USD", Currency("USD"), 1, 0), ), ) @pytest.mark.usefixtures("simple_rates") def test_get_rate(source, target, expected, django_assert_num_queries, queries): with django_assert_num_queries(queries): assert get_rate(source, target) == expected @pytest.mark.parametrize( "source, target, expected", ( ("NOK", "SEK", Decimal("1.067732610555839085161462146")), ("SEK", "NOK", Decimal("0.9365640705489186883886537319")), ),
import pytest from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.models import _get_rate, convert_money, get_rate from djmoney.money import Currency, Money from tests._compat import patch pytestmark = pytest.mark.django_db @pytest.mark.parametrize('source, target, expected', ( ('USD', 'USD', 1), ('USD', 'EUR', 2), ('EUR', 'USD', Decimal('0.5')), (Currency('USD'), 'USD', 1), ('USD', Currency('USD'), 1), )) @pytest.mark.usefixtures('simple_rates') def test_get_rate(source, target, expected): assert get_rate(source, target) == expected def test_unknown_currency(): with pytest.raises(MissingRate, match='Rate USD \\-\\> EUR does not exist'): get_rate('USD', 'EUR') def test_string_representation(backend): assert str(backend) == backend.name