diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-03-22 22:54:01 +0100 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2017-03-22 22:54:01 +0100 |
commit | 635ea32a1539001c0ce2318210f8b4cdfe6692d1 (patch) | |
tree | 9de180bbbcdfa4e6283eb4ac33c9bfd21e7d066a /talerbank | |
parent | a37e84da7c180ac44c6b9c43ab4219be67d375b8 (diff) | |
download | bank-635ea32a1539001c0ce2318210f8b4cdfe6692d1.tar.gz bank-635ea32a1539001c0ce2318210f8b4cdfe6692d1.tar.bz2 bank-635ea32a1539001c0ce2318210f8b4cdfe6692d1.zip |
Getting rid of the sign in front of amount's "value" field,
and implementing a flag-based way of accounting debts.
Any bank account has now a 'debit' field, and whenever it
turns True then the user is in debt and the balance indicates
how much debt the user has.
Diffstat (limited to 'talerbank')
-rw-r--r-- | talerbank/app/amounts.py | 20 | ||||
-rw-r--r-- | talerbank/app/migrations/0001_initial.py | 3 | ||||
-rw-r--r-- | talerbank/app/models.py | 1 | ||||
-rw-r--r-- | talerbank/app/tests.py | 64 | ||||
-rw-r--r-- | talerbank/app/views.py | 14 |
5 files changed, 95 insertions, 7 deletions
diff --git a/talerbank/app/amounts.py b/talerbank/app/amounts.py index d76eaff..8f713c4 100644 --- a/talerbank/app/amounts.py +++ b/talerbank/app/amounts.py @@ -19,11 +19,15 @@ import re import math import logging +from django.conf import settings logger = logging.getLogger(__name__) FRACTION = 100000000 +def get_zero(): + return dict(value=0, fraction=0, currency=settings.TALER_CURRENCY) + def amount_add(a1, a2): assert(a1["currency"] == a2["currency"]) a1_float = floatify(a1) @@ -36,9 +40,21 @@ def amount_sub(a1, a2): a2_float = floatify(a2) sub = a1_float - a2_float fmt = "%s %s" % (str(sub), a2["currency"]) - logger.info(fmt) return parse_amount(fmt) +# Return -1 if a1 < a2, 0 if a1 == a2, 1 if a1 > a2 +def amount_cmp(a1, a2): + assert(a1["currency"] == a2["currency"]) + a1_float = floatify(a1) + a2_float = floatify(a2) + + if a1_float < a2_float: + return -1 + elif a1_float == a2_float: + return 0 + + return 1 + def floatify(amount_dict): return amount_dict['value'] + (float(amount_dict['fraction']) / float(FRACTION)) @@ -52,7 +68,7 @@ def parse_amount(amount_str): Parse amount of return None if not a valid amount string """ - parsed = re.search("^\s*((-)?[0-9]+)(\.[0-9]+)? ([-_*A-Za-z0-9]+)\s*$", amount_str) + parsed = re.search("^\s*([0-9]+)(\.[0-9]+)? ([-_*A-Za-z0-9]+)\s*$", amount_str) if not parsed: return None value = int(parsed.group(1)) diff --git a/talerbank/app/migrations/0001_initial.py b/talerbank/app/migrations/0001_initial.py index 983ed1e..ff05150 100644 --- a/talerbank/app/migrations/0001_initial.py +++ b/talerbank/app/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.10.2 on 2017-03-20 16:24 +# Generated by Django 1.10.3 on 2017-03-22 20:22 from __future__ import unicode_literals from django.conf import settings @@ -20,6 +20,7 @@ class Migration(migrations.Migration): name='BankAccount', fields=[ ('is_public', models.BooleanField(default=False)), + ('debit', models.BooleanField(default=False)), ('balance_value', models.IntegerField(default=0)), ('balance_fraction', models.IntegerField(default=0)), ('balance', models.FloatField(default=0)), diff --git a/talerbank/app/models.py b/talerbank/app/models.py index f87caa2..f1c3485 100644 --- a/talerbank/app/models.py +++ b/talerbank/app/models.py @@ -22,6 +22,7 @@ from django.db import models class BankAccount(models.Model): is_public = models.BooleanField(default=False) + debit = models.BooleanField(default=False) balance_value = models.IntegerField(default=0) balance_fraction = models.IntegerField(default=0) balance = models.FloatField(default=0) diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py index 7b437f1..a0236b5 100644 --- a/talerbank/app/tests.py +++ b/talerbank/app/tests.py @@ -20,6 +20,8 @@ from django.conf import settings from django.contrib.auth.models import User from .models import BankAccount from . import urlsadmin, urls +from . import amounts +from .views import wire_transfer import logging @@ -63,11 +65,9 @@ class LoginTestCase(TestCase): currency=settings.TALER_CURRENCY) user_account.save() - def tearDown(self): clearDb() - def test_login(self): c = Client() response = c.post(reverse("login", urlconf=urls), @@ -75,3 +75,63 @@ class LoginTestCase(TestCase): "password": "test_password"}, follow=True) self.assertIn(("/profile", 302), response.redirect_chain) + + +class AmountTestCase(TestCase): + + def test_cmp(self): + a1 = dict(value=1, fraction=0, currency="X") + _a1 = dict(value=1, fraction=0, currency="X") + a2 = dict(value=2, fraction=0, currency="X") + self.assertEqual(-1, amounts.amount_cmp(a1, a2)) + self.assertEqual(1, amounts.amount_cmp(a2, a1)) + self.assertEqual(0, amounts.amount_cmp(a1, _a1)) + + +# This tests whether a bank account goes red and then +# goes green again +class DebitTestCase(TestCase): + + def setUp(self): + u = User.objects.create_user(username='U') + u0 = User.objects.create_user(username='U0') + ua = BankAccount(user=u, currency=settings.TALER_CURRENCY) + u0a = BankAccount(user=u0, currency=settings.TALER_CURRENCY) + + ua.save() + u0a.save() + + def test_green(self): + u = User.objects.get(username='U') + ub = BankAccount.objects.get(user=u) + self.assertEqual(False, ub.debit) + + def test_red(self): + u = User.objects.get(username='U') + u0 = User.objects.get(username='U0') + + ub = BankAccount.objects.get(user=u) + ub0 = BankAccount.objects.get(user=u0) + + wire_transfer(dict(value=10, fraction=0, currency=settings.TALER_CURRENCY), + ub0, + ub, + "Go green") + tmp = amounts.get_zero() + tmp["value"] = 10 + + self.assertEqual(0, amounts.amount_cmp(ub.balance_obj, tmp)) + self.assertEqual(False, ub.debit) + self.assertEqual(True, ub0.debit) + + wire_transfer(dict(value=11, fraction=0, currency=settings.TALER_CURRENCY), + ub, + ub0, + "Go red") + + self.assertEqual(True, ub.debit) + self.assertEqual(False, ub0.debit) + + tmp["value"] = 1 + + self.assertEqual(0, amounts.amount_cmp(ub0.balance_obj, tmp)) diff --git a/talerbank/app/views.py b/talerbank/app/views.py index 57dc42a..f93df1c 100644 --- a/talerbank/app/views.py +++ b/talerbank/app/views.py @@ -391,8 +391,18 @@ def wire_transfer(amount, credit_account=credit_account, debit_account=debit_account, subject=subject) - debit_account.balance_obj = amounts.amount_sub(debit_account.balance_obj, amount) - credit_account.balance_obj = amounts.amount_add(credit_account.balance_obj, amount) + + if -1 == amounts.amount_cmp(debit_account.balance_obj, amount): + debit_account.debit = True + debit_account.balance_obj = amounts.amount_sub(amount, debit_account.balance_obj) + else: + debit_account.balance_obj = amounts.amount_sub(debit_account.balance_obj, amount) + + if 1 == amounts.amount_cmp(amount, credit_account.balance_obj): + credit_account.debit = False + credit_account.balance_obj = amounts.amount_sub(amount, credit_account.balance_obj) + else: + credit_account.balance_obj = amounts.amount_add(credit_account.balance_obj, amount) with transaction.atomic(): debit_account.save() |