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.
 
 
 
 

177 lines
5.5 KiB

import datetime
import uuid
from functools import reduce
from decimal import Decimal
from django.conf import settings
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.views.generic.edit import BaseFormView
from cart.utils import Cart
from cart.models import Buying, Discount, Offer
from core.views import ProtectedListView, ProtectedTemplateView, ProtectedView, ProtectedFormView
from .forms import (
CartRemoveBuyingForm,
DiscountForm,
CartAddInlineForm, CartCheckoutForm
)
class CartAddView(BaseFormView):
http_method_names = ('post',)
form_class = CartAddInlineForm
def get_success_url(self):
return self.request.META.get('HTTP_REFERRER', reverse_lazy('products:product_list'))
def form_valid(self, form):
self.request.cart.add(offer_id=form.cleaned_data['offer'].product_id, quantity=form.cleaned_data['amount'])
return super().form_valid(form)
class CartRemoveView(BaseFormView):
http_method_names = ('post',)
model = Offer
form_class = CartRemoveBuyingForm
def get_success_url(self):
return self.request.META.get('HTTP_REFERRER', reverse_lazy('products:product_list'))
def form_valid(self, form):
self.request.cart.remove(form.cleaned_data['offer'])
return super().form_valid()
class CartView(ProtectedListView):
model = Offer
paginate_by = settings.DEFAULT_PAGE_AMOUNT
context_object_name = 'offer_items'
template_name = 'cart/cart.html'
ordering = '-create_at'
title = _('Корзина')
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(product__id__in=self.request.cart.keys())
def get_total_price(self, object_list):
return reduce(
lambda initial, offer: initial + offer.price * Decimal(self.request.cart[offer.product_id]['quantity']),
object_list,
Decimal(0)
)
def get_total_cashback(self, object_list):
return reduce(
lambda initial, offer: initial + offer.cashback * Decimal(self.request.cart[offer.product_id]['quantity']),
object_list,
Decimal(0)
)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs)
context['title'] = self.title
context['total_price'] = self.get_total_price(self.object_list)
context['total_price_currency'] = context['total_cashback_currency'] = self.object_list.first().currency.sign
context['total_cashback'] = self.get_total_cashback(self.object_list)
return context
class CartCheckoutView(ProtectedFormView):
http_method_names = ('get', 'post',)
template_name = 'cart/checkout.html'
form_class = CartCheckoutForm
def get_form_kwargs(self):
return super().get_form_kwargs()
def form_valid(self, form):
return super().form_valid(form)
class CartConfirmView(ProtectedTemplateView):
http_method_names = ('post',)
template_name = 'cart/confirm.html'
class BuyingsHistory(ProtectedListView):
model = Buying
paginate_by = settings.DEFAULT_PAGE_AMOUNT
context_object_name = 'bought_item_list'
ordering = '-create_at'
template_name = 'cart/bought_history.html'
title = _('История покупок')
def get_queryset(self):
qs = super().get_queryset()
return qs.filter(user=self.request.user)
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs)
context['title'] = self.title
return context
# Discount views # @TODO: TEST FOR PRODUCTION
class PointsApply(ProtectedTemplateView):
http_method_names = ('post',)
def dispatch(self, request, *args, **kwargs):
super().dispatch(request, *args, **kwargs)
self.request.session['points'] = True
return redirect('cart:buyings')
class PointsRevoke(ProtectedView):
http_method_names = ('post',)
def dispatch(self, request, *args, **kwargs):
super().dispatch(request, *args, **kwargs)
self.request.session.pop('points', None)
return redirect('cart:buyings')
class DiscountApply(ProtectedFormView):
http_method_names = ('post',)
form_class = DiscountForm
def form_valid(self, form):
now = datetime.now()
code = form.cleaned_data['code']
try:
discount = Discount.objects.get(code__iexact=code,
valid_from__lte=now,
valid_to__gte=now,
active=True)
self.request.session['discount_id'] = discount.id
except Discount.DoesNotExist:
self.request.session['discount_id'] = None
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('cart:buyings')
class CreateDiscount(ProtectedFormView):
http_method_names = ('post',)
form_class = DiscountForm
def form_valid(self, form):
now = datetime.now()
Discount.objects.update_or_create(
user=self.request.user,
defaults={'code': str(uuid.uuid4()),
'valid_from': now,
'valid_to': now + datetime.timedelta(days=7),
'active': True}
)
return super().form_valid(form)
def get_success_url(self):
return reverse_lazy('cabinet:index')