You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

241 lines
7.3 KiB

from django.views import generic
from django import forms
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.core import paginator
from cashonly.core.models import *
from cashonly.core.services import AccountManager
from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy
from django.db import IntegrityError
# import cashonly.core.version
import datetime
# def version_number_context_processor(request):
# return {'version_number': cashonly.version.CASHONLY_VERSION}
@login_required
def overview(request):
try:
a = request.user.account
except User.account.RelatedObjectDoesNotExist:
return render(
request,
"cashonly/web/index.html",
{"latest_transactions": [], "latest_purchases": []},
)
time = datetime.datetime.now() - datetime.timedelta(hours=12)
transactions = (
Transaction.objects.filter(account=a)
.filter(timestamp__gte=time)
.order_by("-timestamp")
)
# FIXME: distinct doesn't work as expected, so fetch 20 rows and hope that
# there are 3 distinct products
purchases = (
Product.objects.filter(saleslogentry__account=a)
.order_by("-saleslogentry__timestamp")
.distinct()[:20]
)
products = []
# Find 3 products
for p in purchases:
if p not in products:
products.append(p)
if len(products) == 3:
break
return render(
request,
"cashonly/web/index.html",
{"latest_transactions": transactions, "latest_purchases": products},
)
class ProductView(generic.DetailView):
model = Product
@login_required
def transactions(request, detailed, page):
a = request.user.account
transactions = Transaction.objects.filter(account=a).order_by("-timestamp")
if page is None:
page = 1
pagi = paginator.Paginator(transactions, 10)
try:
transaction_list = pagi.page(page)
except paginator.EmptyPage:
transaction_list = paginator.page(paginator.num_pages)
return render(
request,
"cashonly/web/transaction_list.html",
{"transaction_list": transaction_list, "detailed": detailed},
)
def products(request, category_id=None):
if category_id is None:
category = None
products = Product.objects.filter(active=True)
else:
category = get_object_or_404(ProductCategory, id=category_id)
products = Product.objects.filter(active=True).filter(category=category)
categories = ProductCategory.objects.all()
return render(
request,
"cashonly/web/product_list.html",
{"product_list": products, "category": category, "categories": categories},
)
@login_required
def buy(request, product_id, confirm=False):
product = get_object_or_404(Product, id=product_id)
if confirm:
accmgr = AccountManager(request.user.account)
if accmgr.buy_product(product, 1):
return redirect("buy_thanks")
else:
return redirect("buy_error")
else:
return render(request, "cashonly/web/buy_confirm.html", {"product": product})
@login_required
def buy_thanks(request):
return render(request, "cashonly/web/buy_thanks.html")
@login_required
def buy_error(request):
return render(request, "cashonly/web/buy_error.html")
class UserSettingsForm(forms.Form):
daily_digest = forms.BooleanField(
required=False, label=gettext_lazy("daily digest")
)
class UserPinForm(forms.Form):
pin = forms.CharField(
max_length=32,
widget=forms.PasswordInput,
label=gettext_lazy("PIN"),
required=False,
)
pin_confirm = forms.CharField(
max_length=32,
widget=forms.PasswordInput,
label=gettext_lazy("PIN (confirmation)"),
required=False,
)
def clean(self):
cleaned_data = super(UserPinForm, self).clean()
if "pin" not in cleaned_data and "pin_confirm" not in cleaned_data:
return cleaned_data
if cleaned_data["pin"] != cleaned_data["pin_confirm"]:
raise forms.ValidationError(_("PINs do not match."))
return cleaned_data
class UserAvatarForm(forms.Form):
avatar = forms.ImageField(label=gettext_lazy("avatar"), required=False)
class UserCardNumberForm(forms.Form):
card_number = forms.CharField(
max_length=32, label=gettext_lazy("card number"), required=False
)
@login_required
def usersettings(request, submit=None):
daily_digest = request.user.account.daily_digest
settings_form = UserSettingsForm({"daily_digest": daily_digest})
pin_form = UserPinForm()
avatar_form = UserAvatarForm()
card_number_form = UserCardNumberForm(
{"card_number": request.user.account.card_number}
)
if request.method == "POST":
if submit == "pin":
pin_form = UserPinForm(request.POST)
if pin_form.is_valid():
pin = pin_form.cleaned_data["pin"]
accmgr = AccountManager(request.user.account)
if pin is not None:
accmgr.set_pin(pin)
else:
accmgr.clear_pin()
return render(request, "cashonly/web/usersettings_saved.html")
elif submit == "settings":
settings_form = UserSettingsForm(request.POST)
if settings_form.is_valid():
daily_digest = settings_form.cleaned_data["daily_digest"]
request.user.account.daily_digest = daily_digest
request.user.account.save()
return render(request, "cashonly/web/usersettings_saved.html")
elif submit == "avatar":
avatar_form = UserAvatarForm(request.POST, request.FILES)
if avatar_form.is_valid():
if "delete" in request.POST:
request.user.account.avatar = None
else:
request.user.account.avatar = avatar_form.cleaned_data["avatar"]
request.user.account.save()
return render(request, "cashonly/web/usersettings_saved.html")
else:
# TODO handle upload error (e.g. wrong mime type?)
pass
elif submit == "card_number":
card_number_form = UserCardNumberForm(request.POST)
# TODO validate card number
if card_number_form.is_valid():
request.user.account.card_number = card_number_form.cleaned_data[
"card_number"
]
try:
request.user.account.save()
except IntegrityError:
return render(
request,
"cashonly/web/usersettings_error.html",
{"msg": _("Card number is already in use.")},
)
return render(request, "cashonly/web/usersettings_saved.html")
else:
pass
# TODO handle error (invalid card number)
return render(
request,
"cashonly/web/usersettings.html",
{
"settings_form": settings_form,
"pin_form": pin_form,
"avatar_form": avatar_form,
"card_number_form": card_number_form,
},
)