summaryrefslogtreecommitdiff
path: root/talerbank
diff options
context:
space:
mode:
authorMarcello Stanisci <marcello.stanisci@inria.fr>2017-03-22 22:54:01 +0100
committerMarcello Stanisci <marcello.stanisci@inria.fr>2017-03-22 22:54:01 +0100
commit635ea32a1539001c0ce2318210f8b4cdfe6692d1 (patch)
tree9de180bbbcdfa4e6283eb4ac33c9bfd21e7d066a /talerbank
parenta37e84da7c180ac44c6b9c43ab4219be67d375b8 (diff)
downloadbank-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.py20
-rw-r--r--talerbank/app/migrations/0001_initial.py3
-rw-r--r--talerbank/app/models.py1
-rw-r--r--talerbank/app/tests.py64
-rw-r--r--talerbank/app/views.py14
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()