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 django.contrib.auth.models import User from cashonly.core.models import * from cashonly.core.services import AccountManager from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_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=ugettext_lazy('daily digest')) class UserPinForm(forms.Form): pin = forms.CharField(max_length=32, widget=forms.PasswordInput, label=ugettext_lazy('PIN'), required=False) pin_confirm = forms.CharField(max_length=32, widget=forms.PasswordInput, label=ugettext_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=ugettext_lazy('avatar'), required=False) class UserCardNumberForm(forms.Form): card_number = forms.CharField(max_length=32, label=ugettext_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})