This commit is contained in:
Anna Sudnitsina 2017-10-31 16:58:10 +03:00
parent c53725b502
commit ab26cc9931
7 changed files with 162 additions and 129 deletions

View File

@ -39,11 +39,8 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls',
'blog',
'imagehost',
'pfm',
'taggit',
# 'taggit',
]
MIDDLEWARE_CLASSES = [
@ -87,8 +84,19 @@ DATABASES = {
'NAME': os.path.join(BASE_DIR, '../db.sqlite3'),
}
}
'''
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mysite',
'USER': 'anya',
'PASSWORD': 'pupsi4ek',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
'''
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators

View File

@ -18,8 +18,7 @@ from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic.base import TemplateView
urlpatterns = patterns('',
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', TemplateView.as_view(template_name='main.html')),
url(r'^pfm/', include('pfm.urls')),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
url(r'^', include('pfm.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -1,17 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from decimal import Decimal
from django.db import models, connection
from django.utils import timezone
from datetime import datetime, date, timedelta
from django.core.exceptions import ValidationError
from decimal import Decimal
class Category(models.Model):
cat_name = models.CharField("Category", max_length=50)
cat_type = models.CharField("Type", max_length=1, choices=(('I', 'Income'), ('E', 'Expence')))
user = models.ForeignKey('auth.user', null=True, blank=True)
budget_type = models.CharField("Type", max_length=1, choices = (('W', 'Weekly'), ('M', 'Monthly'), ('Y', 'Yearly')), default='M')
budget_amount = models.DecimalField("Amount", max_digits=10, decimal_places=2, default=0)
cat_type = models.CharField(
"Type", max_length=1, choices=(("I", "Income"), ("E", "Expence"))
)
user = models.ForeignKey("auth.user", null=True, blank=True)
budget_type = models.CharField(
"Type",
max_length=1,
choices=(("W", "Weekly"), ("M", "Monthly"), ("Y", "Yearly")),
default="M",
)
budget_amount = models.DecimalField(
"Amount", max_digits=10, decimal_places=2, default=0
)
def natural_key(self):
return self.cat_name
@ -20,44 +30,36 @@ class Category(models.Model):
return self.cat_name
def cat_sum(self):
cur = connection.cursor()
month = date.today().month
year = date.today().year
cur.execute("""SELECT SUM(tr_amount) from pfm_transaction as t JOIN pfm_category as c
ON t.tr_cat_id = c.id WHERE c.id=%s AND tr_type='E' AND date_part('month', t.tr_date)=%s AND date_part('year', t.tr_date)=%s""", (self.id, month, year ))
try:
return float(cur.fetchone()[0])
except:
return 0
cur.close()
from django.db.models import Sum
data = Transaction.objects.filter(
tr_cat=self.id,
tr_date__gte=timezone.now().replace(
day=1, hour=0, minute=0, second=0, microsecond=0
),
).aggregate(Sum("tr_amount"))
return float(data["tr_amount__sum"]) if data["tr_amount__sum"] else 0
def minus_sum(self):
return (self.cat_sum()*(-1))
'''def budget(self):
cur = connection.cursor()
cur.execute("""SELECT amount FROM pfm_budget WHERE cat_id=:ID """, {"ID": self.id})
try: return float(cur.fetchone()[0])
except: return 0
cur.close()'''
return self.cat_sum() * (-1)
def balance(self):
return -self.budget()
def ratio(self):
try: return int(Decimal(self.cat_sum())/self.budget_amount*100)
except: return 100
if ratio(self)>100:
if self.budget_amount == 0:
return 100
return min(100, int(Decimal(self.cat_sum()) / self.budget_amount * 100))
class Meta:
verbose_name_plural = "Categories"
class Account(models.Model):
acc_name = models.CharField("Account", max_length=50)
acc_balance = models.DecimalField("Balance", max_digits=10, decimal_places=2)
acc_currency = models.CharField("Currency", max_length=3)
user = models.ForeignKey('auth.user', null=True, blank=True)
user = models.ForeignKey("auth.user", null=True, blank=True)
def natural_key(self):
return self.acc_name
@ -74,69 +76,90 @@ class Account(models.Model):
def count(self, SQL):
cur = connection.cursor()
cur.execute(SQL, (self.id,))
try: return float(cur.fetchone()[0])
except: return 0
try:
return float(cur.fetchone()[0])
except TypeError:
return 0
cur.close()
def exp(self): return self.count(Account.SQL_exp)
def exp(self):
return self.count(Account.SQL_exp)
def inc(self): return self.count(Account.SQL_inc)
def inc(self):
return self.count(Account.SQL_inc)
def tr_in(self):
cur = connection.cursor()
cur.execute("""SELECT SUM(tr_amount) from pfm_transfer as t JOIN pfm_account as a
ON t.to_acc_id = a.id WHERE to_acc_id=%s""", (self.id,))
cur.execute(
"""SELECT SUM(tr_amount) from pfm_transfer as t JOIN pfm_account as a
ON t.to_acc_id = a.id WHERE to_acc_id=%s""",
(self.id,),
)
try:
return float(cur.fetchone()[0])
except:
except TypeError:
return 0
cur.close()
def tr_out(self):
cur = connection.cursor()
cur.execute("""SELECT SUM(tr_amount) from pfm_transfer as t JOIN pfm_account as a
ON t.from_acc_id = a.id WHERE from_acc_id=%s""", (self.id,))
cur.execute(
"""SELECT SUM(tr_amount) from pfm_transfer as t JOIN pfm_account as a
ON t.from_acc_id = a.id WHERE from_acc_id=%s""",
(self.id,),
)
try:
return float(cur.fetchone()[0])
except:
except TypeError:
return 0
cur.close()
def rest(self):
return (float(self.acc_balance) - self.count(Account.SQL_exp) -
self.tr_out() + self.count(Account.SQL_inc) + self.tr_in())
return (
float(self.acc_balance)
- self.count(Account.SQL_exp)
- self.tr_out()
+ self.count(Account.SQL_inc)
+ self.tr_in()
)
class Transaction(models.Model):
tr_acc = models.ForeignKey(Account)
tr_cat = models.ForeignKey(Category)
tr_type = models.CharField("Type", max_length=1, choices=(('I', 'Income'), ('E', 'Expence')), default='E')
tr_amount = models.DecimalField("Amount", max_digits=10, decimal_places=2, default='0.00')
tr_type = models.CharField(
"Type", max_length=1, choices=(("I", "Income"), ("E", "Expence")), default="E"
)
tr_amount = models.DecimalField(
"Amount", max_digits=10, decimal_places=2, default="0.00"
)
tr_note = models.CharField(max_length=100, null=True, blank=True)
tr_date = models.DateField(default=timezone.now)
pub_date = models.DateTimeField(blank=True, null=True)
user = models.ForeignKey('auth.user', blank=True, null=True)
user = models.ForeignKey("auth.user", blank=True, null=True)
def publish(self):
self.pub_date = timezone.now()
self.save()
def __unicode__(self):
return '%s,%s,%s,%s' % (self.tr_cat, self.tr_acc, self.tr_amount, self.tr_date.strftime("%d.%m.%Y"))
return "%s,%s,%s,%s" % (
self.tr_cat,
self.tr_acc,
self.tr_amount,
self.tr_date.strftime("%d.%m.%Y"),
)
def sum_tr():
cur = connection.cursor()
cur.execute("SELECT SUM(tr_amount) from pfm_transaction WHERE tr_date > :D", {"D": date.today()-timedelta(days=30)})
return cur.fetchone()
cur.close()
class Transfer(models.Model):
from_acc = models.ForeignKey(Account, related_name="to_acc")
to_acc = models.ForeignKey(Account, related_name="from_acc")
tr_amount = models.DecimalField("Amount", max_digits=10, decimal_places=2)
tr_date = models.DateTimeField(default=timezone.now)
user = models.ForeignKey('auth.user', blank=True, null=True)
user = models.ForeignKey("auth.user", blank=True, null=True)
def publish(self):
self.save()
def publish(self): self.save()
def __unicode__(self):
return '%s >>> %s, %s' % (self.from_acc, self.to_acc, self.tr_amount)
return "%s >>> %s, %s" % (self.from_acc, self.to_acc, self.tr_amount)

View File

@ -13,7 +13,7 @@
<!--script type="text/javascript" src="/js/materialize.min.js"></script-->
<script type="text/javascript" src="{% static 'js/scripts.js' %}"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="/css/materialize.min.css" media="screen,projection"/>
<link type="text/css" rel="stylesheet" href="{% static 'css/materialize.min.css' %}" media="screen,projection"/>
<style>select{
position: relative;
cursor: pointer;
@ -46,7 +46,7 @@
<!-- Dropdown Structure -->
<ul id="dropdown-content">
<li><a class="blue-text" href="/admin">Admin</a></li>
<li><a class="blue-text" href="/pfm/logout">Exit</a></li>
<li><a class="blue-text" href="/logout">Exit</a></li>
</ul>
<!-- Navigation -->

View File

@ -1,5 +1,5 @@
{% extends 'pfm/base.html' %}
{% load pagination_tags %}
{% block content %}
<style type="text/css">

View File

@ -1,9 +1,9 @@
{% extends 'pfm/base.html' %}
{% load pagination_tags %}
{% block content %}
<div class="grid-example col s12">
<a class="waves-effect waves-light btn-large blue" style="display: block; float: right; margin: 1px" onclick = 'ModalForm(0); location.href = "#new"'>New transaction</a>
<a class="waves-effect waves-light btn-large blue" style="display: block; float: right; margin: 1px" href="/pfm/tr_edit">Massive update</a>
<a class="waves-effect waves-light btn-large blue" style="display: block; float: right; margin: 1px" href="/tr_edit">Massive update</a>
<p class="flow-text">Журнал операций</p> </div>
<table class="striped bordered">

View File

@ -17,43 +17,49 @@ import calendar
import requests
from json import loads
def test(request):
response = requests.get('https://query.yahooapis.com/v1/public/yql?q=select+*+from+yahoo.finance.xchange+where+pair+=+%22USDRUB,%20EURRUB,%20BYNRUB%22&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=')
status = loads(response.content)
status = status["query"]["results"]["rate"]
#return HttpResponse(status)
return render(request, 'pfm/test.html', {'status': status})
#return render(request, 'pfm/test.html', {'form': form, })
url = 'https://www.cbr-xml-daily.ru/daily_utf8.xml'
response = requests.get(url)
return render(request, 'pfm/test.html', {'status': response.content})
def json(request):
transactions = Transaction.objects.all()
data = serializers.serialize("json", transactions, use_natural_foreign_keys=True)
data_dict = loads(data)
return JsonResponse(data_dict, safe=False)
def tr_list(request):
# TODO: at first load all categories are available - bug!
tr_redir_url = '/transactions/#!'
tr_list = Transaction.objects.filter(user=request.user).order_by('-tr_date')
paginator = Paginator(tr_list, 10)
page = request.GET.get('page')
try: trs = paginator.page(page)
except PageNotAnInteger: trs = paginator.page(1)
except EmptyPage: trs = paginator.page(paginator.num_pages)
form = NewTransaction(user=request.user)
try:
trs = paginator.page(page)
except PageNotAnInteger:
trs = paginator.page(1)
except EmptyPage:
trs = paginator.page(paginator.num_pages)
if request.method == 'GET' and 'type' in request.GET:
if request.GET['type'] == 'E':
form = NewTransactionExp(request.POST, user=request.user)
return HttpResponse (form['tr_cat'])
#return render(request, 'pfm/tr_cat_selector.html', {'form': form,})
return HttpResponse(form['tr_cat'])
elif request.GET['type'] == 'I':
form = NewTransactionInc(request.POST, user=request.user)
return HttpResponse (form['tr_cat'])
#return render(request, 'pfm/tr_cat_selector.html', {'form': form,})
return HttpResponse(form['tr_cat'])
if request.method == 'GET' and 'id' in request.GET:
if request.GET['id'] == '0':
form = NewTransaction(user=request.user)
return render(request, 'pfm/tr_edit_form.html', {'form': form,})
return render(request, 'pfm/tr_edit_form.html', {'form': form, })
tr = Transaction.objects.get(id=request.GET['id'])
type = tr.tr_type
if type == 'E':
form = NewTransactionExp(instance=Transaction.objects.get(id=request.GET['id']), user=request.user)
return render(request, 'pfm/tr_edit_form.html', {'form': form,})
if type == 'I':
form = NewTransactionInc(instance=Transaction.objects.get(id=request.GET['id']), user=request.user)
return render(request, 'pfm/tr_edit_form.html', {'form': form,})
mapping = {'E': NewTransactionExp, 'I': NewTransactionInc}
form = mapping[tr.tr_type](instance=Transaction.objects.get(id=request.GET['id']), user=request.user)
return render(request, 'pfm/tr_edit_form.html', {'form': form, })
else:
if request.method == "POST" and request.POST.get('action') == 'create':
form = NewTransaction(request.POST, user=request.user)
@ -62,38 +68,36 @@ def tr_list(request):
tr.published_date = timezone.now()
tr.user = request.user
tr.save()
return redirect('/pfm/transactions/#!')
return redirect(tr_redir_url)
else:
print('Not valid!', form.errors)
elif request.POST.get('action') == 'edit':
transaction = Transaction.objects.get(id=request.POST['id'])
form = NewTransaction(request.POST, instance = transaction, user=request.user )
form = NewTransaction(request.POST, instance=transaction, user=request.user)
if form.is_valid():
transaction = form.save(commit=False)
transaction.user = request.user
transaction.save()
return redirect('/pfm/transactions/#!')
return redirect(tr_redir_url)
elif request.method == 'POST' and request.POST.get('action') == 'delete':
form = NewTransaction(request.POST, user=request.user)
transaction = Transaction.objects.get(id=request.POST.get('id'))
transaction.delete()
return redirect('/pfm/transactions/#!')
return redirect(tr_redir_url)
else:
form=NewTransaction(user=request.user)
form = NewTransaction(user=request.user)
return render(request, 'pfm/transactions.html', {'form': form, 'trs': trs})
def acc_list(request):
acc_redir_url = '/account/#!'
list = Account.objects.filter(user=request.user)
tr_form = NewTransfer(request.POST, user=request.user)
trs = Transfer.objects.filter(user=request.user)
#response = requests.get('https://query.yahooapis.com/v1/public/yql?q=select+*+from+yahoo.finance.xchange+where+pair+=+%22USDRUB,%20EURRUB,%20BYNRUB%22&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=')
#status = loads(response.content)
#status = status["query"]["results"]["rate"]
if request.POST.get('action') == 'delete':
account = Account.objects.get(id=request.POST.get('id'))
account.delete()
return redirect('/pfm/account/#!')
return redirect(acc_redir_url)
#return redirect('pfm.views.acc_list')
elif request.POST.get('action') == 'create':
form = NewAccount(request.POST)
@ -101,7 +105,7 @@ def acc_list(request):
account = form.save(commit=False)
account.user = request.user
account.save()
return redirect('/pfm/account/#!')
return redirect(acc_redir_url)
elif request.POST.get('action') == 'edit':
acc = Account.objects.get(id=request.POST['id'])
form = NewAccount(request.POST, instance = acc )
@ -109,15 +113,14 @@ def acc_list(request):
account = form.save(commit=False)
account.user = request.user
account.save()
#return redirect('pfm.views.acc_list')
return redirect('/pfm/account/#!')
return redirect(acc_redir_url)
elif request.POST.get('action') == 'transfer':
if tr_form.is_valid():
transfer = tr_form.save(commit=False)
transfer.user = request.user
transfer.save()
return redirect('/pfm/account/#!')
return redirect(acc_redir_url)
else:
try:
form = NewAccount(instance=Account.objects.get(id=request.GET['id']))
@ -127,11 +130,6 @@ def acc_list(request):
#connection. queries
return render(request, 'pfm/accounts.html', {'list': list, 'form': form, 'tr_form': tr_form, 'trs': trs})
def json(request):
transactions = Transaction.objects.all()
data = serializers.serialize("json", transactions, use_natural_foreign_keys=True)
data_dict = loads(data)
return JsonResponse(data_dict, safe=False)
def massive_cat_edit(request):
Cat_formset = modelformset_factory(Category, form=NewCategory, can_delete=True, extra=0)
@ -149,18 +147,19 @@ def massive_cat_edit(request):
context = {'form': form, }
return render(request, 'pfm/cat_edit.html', context)
def massive_tr_edit(request):
TestTrModel1 = modelformset_factory(Transaction, form=NewTransaction, can_delete=True, extra=0)
if request.method == "POST":
form = TestTrModel1(request.POST, form_kwargs={'user': request.user})
paginator = Paginator(form, 2)
page = request.GET.get('page')
try:
trs = paginator.page(page)
except PageNotAnInteger:
trs = paginator.page(1)
except EmptyPage:
trs = paginator.page(paginator.num_pages)
# paginator = Paginator(form, 2)
# page = request.GET.get('page')
# try:
# trs = paginator.page(page)
# except PageNotAnInteger:
# trs = paginator.page(1)
# except EmptyPage:
# trs = paginator.page(paginator.num_pages)
if form.is_valid():
transactions = form.save(commit=False)
for transaction in transactions:
@ -197,6 +196,7 @@ def main(request):
date_today = datetime.now()
return render(request, 'pfm/base.html', {'accounts': accounts, 'transactions': transactions, 'categories': categories, 'sum_total': sum_total, 'date_today': date_today})
def get_csv(request):
transactions = Transaction.objects.defer('tr_date').filter(user=request.user)
response = HttpResponse(content_type='text/csv')
@ -208,6 +208,7 @@ def get_csv(request):
return response
def cat_list(request):
categories = Category.objects.filter(user=request.user, cat_type='E')
sum_total = Transaction.objects.filter(user=request.user, tr_date__month =date.today().month, tr_date__year=date.today().year, tr_type='E').aggregate(Sum('tr_amount'))['tr_amount__sum']
@ -230,7 +231,7 @@ def cat_list(request):
category = form.save(commit=False)
category.user = request.user
category.save()
return redirect('/pfm/category/#!')
return redirect('/category/#!')
elif request.POST.get('action') == 'edit':
print request.POST
cat = Category.objects.get(id=request.POST['id'])
@ -239,7 +240,7 @@ def cat_list(request):
category = form.save(commit=False)
category.user = request.user
category.save()
return redirect('/pfm/category/#!')
return redirect('/category/#!')
# return redirect('pfm.views.cat_list')
else:
print('Not valid!', form.errors)
@ -253,6 +254,7 @@ def cat_list(request):
return render(request, 'pfm/categories.html', {'form': form, 'categories': categories, 'sum_total': sum_total, 'budget_total': budget_total, 'total_balance': total_balance,
'progress': progress})
def reports(request):
categories = Category.objects.filter(transaction__user=request.user,
transaction__tr_date__month=date.today().month,
@ -299,6 +301,7 @@ def reports(request):
return render(request, 'pfm/reports.html', context)
return render(request, 'pfm/reports.html', context)
def upload_tr(request):
if request.method == 'POST':
form = Upload(request.POST, request.FILES)