Implemented first part for VirtualTransactions.

See Ticket #4
This commit is contained in:
Sebastian Lohff 2011-10-25 15:47:10 +02:00
parent 4e93c66b64
commit c3100ad09a
5 changed files with 119 additions and 24 deletions

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from models import Transaction, TransactionType from models import Transaction, TransactionType, VirtualTransaction
from django.contrib import admin from django.contrib import admin
class TransactionAdmin(admin.ModelAdmin): class TransactionAdmin(admin.ModelAdmin):
@ -23,3 +23,4 @@ class TransactionAdmin(admin.ModelAdmin):
admin.site.register(Transaction, TransactionAdmin) admin.site.register(Transaction, TransactionAdmin)
admin.site.register(TransactionType) admin.site.register(TransactionType)
admin.site.register(VirtualTransaction)

View File

@ -1,9 +1,13 @@
# -*- coding: utf-8 -*-
from django import forms from django import forms
from models import Transaction from models import Transaction, VirtualTransaction
from main.fields import CurrencyField from main.fields import CurrencyField
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
class TransactionForm(forms.ModelForm): class TransactionForm(forms.ModelForm):
""" ModelForm for :class:`Transactions <Transaction>` with a currency field """ """ ModelForm for :class:`Transactions <Transaction>` with a currency field. """
amount = CurrencyField(label='Betrag') amount = CurrencyField(label='Betrag')
class Meta: class Meta:
model = Transaction model = Transaction
@ -12,6 +16,24 @@ class TransactionForm(forms.ModelForm):
data = self.cleaned_data['amount'] data = self.cleaned_data['amount']
return data return data
def clean(self): def clean(self):
# needed to enforce TransactionTypes needsCheck "default value"
cleaned_data = super(TransactionForm, self).clean() cleaned_data = super(TransactionForm, self).clean()
self.instance.checked = not cleaned_data['transactionType'].needsCheck self.instance.checked = not cleaned_data['transactionType'].needsCheck
return cleaned_data return cleaned_data
class VirtualTransactionForm(forms.ModelForm):
""" ModelForm for :class:`Virtual Transactions <VirtualTransaction>` with a
currency field. """
recipient = forms.CharField(max_length=100)
amount = CurrencyField(label='Betrag')
class Meta:
model = VirtualTransaction
exclude = ('user', 'dateTime')
def clean_recipient(self):
try:
user = User.objects.get(username=self.cleaned_data['recipient'])
except User.DoesNotExist:
raise ValidationError(u"Emfpänger '%s' konnte nicht gefunden werden" % self.cleaned_data['user'])
return user

View File

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from django.db import models from django.db import models
from django.core.validators import * from django.core.validators import *
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.deletion import SET_NULL
from django.db.models.signals import pre_delete
from decimal import Decimal from decimal import Decimal
@ -19,7 +21,7 @@ class Transaction(models.Model):
"""Represents a money transaction into the users account. """ """Represents a money transaction into the users account. """
user = models.ForeignKey(User) user = models.ForeignKey(User)
transactionType = models.ForeignKey(TransactionType, verbose_name='Typ') transactionType = models.ForeignKey(TransactionType, verbose_name='Typ')
dateTime = models.DateTimeField() dateTime = models.DateTimeField(auto_now_add=True)
amount = models.DecimalField(max_digits=8, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))]) amount = models.DecimalField(max_digits=8, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))])
checked = models.BooleanField(default=False) checked = models.BooleanField(default=False)
@ -44,4 +46,44 @@ class Transaction(models.Model):
profile.save() profile.save()
super(Transaction, self).delete(*args, **kwargs) super(Transaction, self).delete(*args, **kwargs)
class VirtualTransaction(models.Model):
""" Represents a transaction between two users. """
user = models.ForeignKey(User, null=True, on_delete=SET_NULL)
recipient = models.ForeignKey(User, related_name='receivedtransaction', null=True, on_delete=SET_NULL, verbose_name=u'Empfänger')
dateTime = models.DateTimeField(auto_now_add=True)
amount = models.DecimalField(max_digits=8, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))], verbose_name='Betrag')
comment = models.CharField(max_length=100, verbose_name='Verwendungszweck')
def __unicode__(self):
return u"%s ==> %s: %s Euro" % (self.user, self.recipient, self.amount)
def save(self, *args, **kwargs):
userProfile = self.user.get_profile()
recipientProfile = self.recipient.get_profile()
amount = None
if self.id == None:
amount = self.amount
else:
oldobj = VirtualTransaction.objects.get(id=self.id)
amount = self.amount - oldobj.amount
userProfile.balance -= amount
recipientProfile.balance += amount
userProfile.save()
recipientProfile.save()
super(VirtualTransaction, self).save(*args, **kwargs)
@staticmethod
def pre_delete_signal(sender, instance, **kwargs):
""" Pre delete signal to ensure consistent balances on object delete. """
# Only revert if both users exist.
if instance.user and instance.recipient:
# revert transaction
print instance.user
print dir(instance)
userProfile = instance.user.get_profile()
recipientProfile = instance.recipient.get_profile()
userProfile.balance += instance.amount
recipientProfile.balance -= instance.amount
userProfile.save()
recipientProfile.save()
pre_delete.connect(VirtualTransaction.pre_delete_signal, sender=VirtualTransaction)

View File

@ -11,8 +11,9 @@
<h2>Konto aufladen</h2> <h2>Konto aufladen</h2>
<form method="POST" class="transaction" action="/transaction/"> <form method="POST" class="transaction" action="/transaction/">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="_formtype" value="normal" />
{{ form.as_table }} {{ form.as_table }}
<input type="submit" class="button" value="Einzahlen"> <input type="submit" class="button" value="Einzahlen" />
</form> </form>
<h3>Kontodaten:</h3> <h3>Kontodaten:</h3>
@ -31,6 +32,21 @@
</tr> </tr>
</table> </table>
<h2>Geld &uuml;berweisen</h2>
{% if transacted %}
{% if error %}
<font color="red"><h1>Beim &uuml;berweisen ist ein Fehler aufgetreten..</h1></font>
{% else %}
<font color="green"><h1>Du hast Geld &uuml;berwiesen.</h1></font>
{% endif %}
{% endif %}
<form method="POST" class="transaction" action="/transaction/">
{% csrf_token %}
<input type="hidden" name="_formtype" value="virtual" />
{{ vform.as_table }}
<input type="submit" class="button" value="&Uuml;berweisen" />
</form>
<h2>Vergangene Transaktionen</h2> <h2>Vergangene Transaktionen</h2>
<table class="textData"> <table class="textData">
<thead> <thead>

View File

@ -2,28 +2,42 @@ from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from models import Transaction, TransactionType from models import Transaction, TransactionType, VirtualTransaction
from forms import TransactionForm from forms import TransactionForm, VirtualTransactionForm
import datetime import datetime
@login_required @login_required
def overview(request): def overview(request):
""" Creates an overview over the users trasnactions, also handles adding money. """ """ Creates an overview over the users transactions, also handles adding and transfering money. """
# create history
history = Transaction.objects.filter(user=request.user).order_by("-dateTime") history = Transaction.objects.filter(user=request.user).order_by("-dateTime")
transacted = False
error = False # create forms
if request.method == 'POST': form = TransactionForm()
transacted = True vform = VirtualTransactionForm()
transaction = Transaction(user=request.user, dateTime=datetime.datetime.now()) transacted = vtransacted = False
form = TransactionForm(request.POST, instance=transaction) error = verror = False
if form.is_valid(): if request.method == 'POST' and request.POST.has_key('_formtype'):
form.save() if request.POST['_formtype'] == "normal":
form = TransactionForm()
transacted = True transacted = True
else: transaction = Transaction(user=request.user)
error = True form = TransactionForm(request.POST, instance=transaction)
form = TransactionForm() if form.is_valid():
else: form.save()
form = TransactionForm() form = TransactionForm()
return render_to_response("transaction/overview.html", {'history': history, 'form': form, 'transacted': transacted, 'error': error}, RequestContext(request)) transacted = True
else:
error = True
form = TransactionForm()
elif request.POST['_formtype'] == "virtual":
vtransacted = True
vtransaction = VirtualTransaction(user=request.user)
vform = VirtualTransactionForm(request.POST, instance=vtransaction)
if vform.is_valid():
vform.save()
vform = VirtualTransactionForm()
vtransacted = True
else:
error = True
return render_to_response("transaction/overview.html", {'history': history, 'form': form, 'transacted': transacted, 'error': error, 'vform': vform, 'vtransacted': vtransacted, 'verror': verror}, RequestContext(request))