django_pfm/pfm/views.py
2020-12-05 22:27:58 +03:00

337 lines
16 KiB
Python

from django.shortcuts import render, redirect, HttpResponseRedirect, get_object_or_404, render_to_response
from django.http import HttpResponse, JsonResponse
from .models import Account, Category, Transaction, Transfer
from .forms import NewTransactionExp, NewTransactionInc, NewTransaction, NewTransaction1, NewAccount, NewCategory, NewTransfer, Upload, BaseTransactionFormSet
from django.forms import ModelChoiceField
from django.forms.models import modelformset_factory, formset_factory
from django.template.context_processors import csrf
from django.utils import timezone
from datetime import datetime, date
from django.db.models import Sum, Avg
from django.db import connection
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.core import serializers
import calendar
import requests
from json import loads
def test(request):
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)
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'])
elif request.GET['type'] == 'I':
form = NewTransactionInc(request.POST, user=request.user)
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, })
tr = Transaction.objects.get(id=request.GET['id'])
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)
if form.is_valid():
tr = form.save(commit=False)
tr.published_date = timezone.now()
tr.user = request.user
tr.save()
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)
if form.is_valid():
transaction = form.save(commit=False)
transaction.user = request.user
transaction.save()
return redirect(tr_redir_url)
elif request.method == 'POST' and request.POST.get('action') == 'delete':
transaction = Transaction.objects.get(id=request.POST.get('id'))
transaction.delete()
return redirect(tr_redir_url)
else:
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)
if request.POST.get('action') == 'delete':
account = Account.objects.get(id=request.POST.get('id'))
account.delete()
return redirect(acc_redir_url)
#return redirect('pfm.views.acc_list')
elif request.POST.get('action') == 'create':
form = NewAccount(request.POST)
if form.is_valid():
account = form.save(commit=False)
account.user = request.user
account.save()
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 )
if form.is_valid():
account = form.save(commit=False)
account.user = request.user
account.save()
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(acc_redir_url)
else:
try:
form = NewAccount(instance=Account.objects.get(id=request.GET['id']))
return HttpResponse(form)
except: form = NewAccount()
tr_form = NewTransfer(user=request.user)
#connection. queries
return render(request, 'pfm/accounts.html', {'list': list, 'form': form, 'tr_form': tr_form, 'trs': trs})
def massive_cat_edit(request):
Cat_formset = modelformset_factory(Category, form=NewCategory, can_delete=True, extra=0)
if request.method == "POST":
form = Cat_formset(request.POST)
if form.is_valid():
categories = form.save(commit=False)
for category in categories:
category.user = request.user
category.save()
form.save()
return redirect('pfm.views.cat_list')
else:
form = Cat_formset(queryset=Category.objects.filter(user=request.user).order_by('id'))
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)
if form.is_valid():
transactions = form.save(commit=False)
for transaction in transactions:
transaction.user = request.user
transaction.save()
form.save()
return redirect('pfm.views.massive_tr_edit')
else:
#show only revalent values to select for the user
query=Transaction.objects.filter(user=request.user).order_by('-tr_date')
paginator = Paginator(query, 8)
page = request.GET.get('page')
try:
trs = paginator.page(page)
except PageNotAnInteger:
trs = paginator.page(1)
except EmptyPage:
trs = paginator.page(paginator.num_pages)
page_query = query.filter(id__in=[tr.id for tr in trs])
form = TestTrModel1(queryset=page_query, form_kwargs={'user': request.user})
context = {'form': form, 'trs': trs}
return render(request, 'pfm/tr_edit.html', context)
@login_required(login_url="login/?next=/pfm/")
def main(request):
accounts = Account.objects.filter(user=request.user).annotate(spent=(Sum('transaction__tr_amount')))
transactions = Transaction.objects.filter(user=request.user).order_by('-tr_date')[:11]
categories = Category.objects.filter(transaction__user=request.user, transaction__tr_date__month=date.today().month,
transaction__tr_date__year=date.today().year,
transaction__tr_type='E').annotate(sum_cat=(Sum('transaction__tr_amount')),
avg_ca=Avg('transaction__tr_amount'))
sum_total = Transaction.objects.filter(user=request.user, tr_date__month =date.today().month, tr_type='E').aggregate(Sum('tr_amount'))['tr_amount__sum']
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')
for item in transactions:
date = item.tr_date.strftime('%d.%m.%Y')
i = '%s,%s,%s,%s,%s,%s\n' % (date, item.tr_type, item.tr_cat, item.tr_acc, item.tr_amount, item.tr_note) #format is equal to uplolad format
#response.write(str(i) + '\n')
response.write(i)
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']
if sum_total == None:
sum_total = 0
budget_total = Category.objects.filter(user=request.user, cat_type='E').aggregate(Sum('budget_amount'))['budget_amount__sum']
try: total_balance = budget_total - sum_total
except: total_balance = 0
try: progress = sum_total/budget_total*100
except: progress = 100
#form_new = modelformset_factory(Category, exclude=('user',))
#form = NewCategory(request.POST)
form = NewCategory(request.POST)
if request.POST.get('action') == 'delete':
category = Category.objects.get(id=request.POST.get('id'))
category.delete()
return redirect('/pfm/category/#!')
elif request.POST.get('action') == 'create':
if form.is_valid():
category = form.save(commit=False)
category.user = request.user
category.save()
return redirect('/category/#!')
elif request.POST.get('action') == 'edit':
print request.POST
cat = Category.objects.get(id=request.POST['id'])
form = NewCategory(request.POST, instance = cat )
if form.is_valid():
category = form.save(commit=False)
category.user = request.user
category.save()
return redirect('/category/#!')
# return redirect('pfm.views.cat_list')
else:
print('Not valid!', form.errors)
else:
try:
form = NewCategory(instance=Category.objects.get(id=request.GET['id']))
return HttpResponse (form)
# return render(request, 'pfm/cat_tmpl.html', {'form': form,})
except:
form = NewCategory()
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,
transaction__tr_date__year=date.today().year,
transaction__tr_type='E').order_by('-sum_cat').annotate(
sum_cat=Sum('transaction__tr_amount')).order_by('-sum_cat')
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']
date_today = datetime.now()
selected_month = datetime.now().month
year_list = [2015, 2016, 2017]
#months = Transaction.objects.datetimes('tr_date', 'month').aggregate(Sum('tr_amount'))
month = date.today().month
year = date.today().year
testing = '%d %d' % (selected_month, year)
datedate = date_today
mon_calendar = calendar.LocaleHTMLCalendar(0, "ru_RU.utf-8").formatmonth(year, month)
context = {'categories': categories, 'datedate': datedate, 'date_today': date_today, 'month': month, 'testing': testing, 'sum_total': sum_total, 'mon_calendar': mon_calendar, 'years': year_list}
if request.method == 'POST':
print request.__dict__
print '------month-------: %s' % (request.POST.get('selected_month'))
selected_month=request.POST.get('selected_month')
selected_year=request.POST.get('selected_year')
if selected_month == '13':
selected_month = 1
selected_year = int(selected_year)+1
if selected_month == '0':
selected_month = 12
selected_year = int(selected_year)-1
print selected_month, selected_year
#months = Transaction.objects.datetimes('tr_date', 'month')
categories = Category.objects.filter(transaction__user=request.user,
transaction__tr_date__month=selected_month,
transaction__tr_date__year=selected_year,
transaction__tr_type='E').annotate(
sum_cat=(Sum('transaction__tr_amount')),
avg_cat=Avg('transaction__tr_amount')).order_by('-sum_cat')
datedate = date(year=int(selected_year), month=int(selected_month), day=1)
sum_total = Transaction.objects.filter(user=request.user, tr_date__month=selected_month, tr_date__year=selected_year, tr_type='E').aggregate(Sum('tr_amount'))['tr_amount__sum']
mon_calendar = calendar.LocaleHTMLCalendar(0, "ru_RU.utf-8").formatmonth(int(selected_year), int(selected_month))
context = {'categories': categories, 'month': selected_month, 'datedate': datedate, 'selected_month': selected_month, 'sum_total': sum_total, 'mon_calendar': mon_calendar}
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)
if form.is_valid:
try:
for row in request.FILES['uploaded']:
row = row.split(',')
print len(row)
transaction = Transaction()
transaction.published_date = timezone.now()
transaction.user = request.user
transaction.tr_date = datetime.strptime(row[0], '%d.%m.%Y')
transaction.tr_type = row[1]
transaction.tr_cat_id = Category.objects.get(cat_name=row[2], user = request.user).id
transaction.tr_acc_id = Account.objects.get(acc_name=row[3], user = request.user).id
if len(row) == 5:
transaction.tr_amount = row[4].strip()
transaction.tr_note = ''
if len(row) == 6:
transaction.tr_amount = row[4]
transaction.tr_note = row[5].strip()
transaction.save()
return redirect('pfm.views.main')
except Account.DoesNotExist:
return HttpResponse ('no such acc: %s' % row[1])
except Category.DoesNotExist:
return HttpResponse ('no such cat: %s' % row[3])
else:
form = Upload()
return render(request, 'pfm/upload.html', {'form': form})