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.
 
 
 
 
 
 

459 lines
16 KiB

import base64
from django.contrib.auth import authenticate, login
from django.core.mail import mail_managers, mail_admins
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import get_object_or_404, redirect, render
from django.template.loader import render_to_string
from django.views.generic import *
from accounts.models import Profile
from accounts.utils import normalize_phone, send_email
from batiskaf.jinja2_ext.html_filters import escape
from main.models import ProductsUpdate
from .models import *
from store.alemtat import AlemTat
from store.cart import Cart, CartItem
from django.contrib import messages
from store.forms import OrderForm, ProductFeedbackForm
from django.http import JsonResponse
from datetime import datetime
from django.conf import settings
from django.contrib.sitemaps import Sitemap
import kkb
class CategoryBaseView(object):
category = None
def _get_full_category(self, categories_string):
cats = categories_string.split('/')
category = get_object_or_404(Category, slug=cats[0])
for c in cats:
if c != category.slug:
category = get_object_or_404(category.childs, slug=c)
return category
class CategoryView(CategoryBaseView, TemplateView):
template_name = 'category.jinja'
brand_pks = []
products_qs = Product.objects.none()
sort = None
is_search = False
is_sale = False
is_leaders = False
ORDER_PARAMETERS = (
('date', 'pk'),
('-date', '-pk'),
('price', 'price_min'),
('-price', '-price_min'),
)
def _get_brand_pks(self):
brand_pks = []
for v in self.request.GET.getlist('brand[]'):
try:
brand_pks.append(int(v))
except:
pass
return brand_pks
def _get_sort(self):
sort = self.request.GET.get('sort', None)
return sort
def paginate(self):
paginate_by = self.request.GET.get('paginate_by', 30)
if paginate_by == 'all':
paginate_by = 10000
paginator = Paginator(self.products_qs, int(paginate_by))
page = self.request.GET.get('page')
try:
self.products_qs = paginator.page(page)
except PageNotAnInteger:
self.products_qs = paginator.page(1)
except EmptyPage:
self.products_qs = paginator.page(paginator.num_pages)
def _get_filter_attributes(self):
for k in self.request.GET:
attr = Attribute.objects.filter(slug=k.replace('[]', ''))
if attr:
attr_values = self.request.GET.getlist(k)
while 'false' in attr_values:
attr_values.remove('false')
attr_values = [v.strip() for v in attr_values]
if attr_values:
self.products_qs = self.products_qs.filter(
product_attributes__attribute__attribute__in=attr,
product_attributes__value__in=attr_values).distinct()
def get_brands_by_products(self):
pass
def get_context_data(self, **kwargs):
retval = super(CategoryView, self).get_context_data()
q = None
if self.is_search:
q = self.request.GET.get('q', '')
self.products_qs = Product.objects.filter(title__icontains=q).order_by('-pk')
brands_pks = [item.brand.pk for item in self.products_qs]
retval['brands'] = Brand.objects.filter(pk__in=brands_pks).order_by(
'title') # list(set(map(lambda item: item.brand, self.products_qs)))
elif self.is_sale:
self.products_qs = Product.objects.filter(variations__discount__gt=0).distinct().order_by('-pk')
brands_pks = [item.brand.pk for item in self.products_qs]
retval['brands'] = Brand.objects.filter(pk__in=brands_pks).order_by('title')
elif self.is_leaders:
brands_pks = [item.brand.pk for item in self.products_qs]
retval['brands'] = Brand.objects.filter(pk__in=brands_pks).order_by('title')
else:
self.category = self._get_full_category(kwargs['categories'])
if not self.category.hide_products:
self.products_qs = self.category.get_all_products().order_by('-pk')
self.brand_pks = self._get_brand_pks()
self.sort = self._get_sort()
if self.brand_pks:
self.products_qs = self.products_qs.filter(
brand__pk__in=self.brand_pks)
if self.sort:
sort_parameter = dict(self.ORDER_PARAMETERS)[self.sort]
preordered_qs = self.products_qs
if sort_parameter in ['price_min', '-price_min']:
preordered_qs = self.products_qs.extra(
select={
'price_min':
'SELECT MIN(price) FROM store_productvariation ' +
'WHERE store_productvariation.product_id ' +
'= store_product.id'
})
self.products_qs = preordered_qs.order_by(sort_parameter)
self._get_filter_attributes()
self.paginate()
retval['category'] = self.category
retval['products'] = self.products_qs
retval['q'] = q
retval['is_sale'] = self.is_sale
return retval
class ProductView(CategoryBaseView, DetailView):
model = Product
template_name = 'product.jinja'
def get(self, request, *args, **kwargs):
self.category = self._get_full_category(kwargs['categories'])
retval = super(ProductView, self).get(request, args, kwargs)
ranee = request.session.get('ranee', [])
#import pdb;pdb.set_trace()
if kwargs['slug'] not in ranee:
ranee.append(kwargs['slug'])
request.session['ranee'] = ranee
return retval
def get_context_data(self, **kwargs):
retval = super(ProductView, self).get_context_data()
retval['category'] = self.category
retval['form'] = ProductFeedbackForm(self.request.POST or None)
retval['updated'] = ProductsUpdate.objects.last()
ranee = self.request.session.get('ranee', [])
#import pdb;pdb.set_trace()
#ranee.pop(kwargs['object'].slug)
retval['ranee'] = []
for i in ranee:
#import pdb; pdb.set_trace()
if kwargs and i != kwargs['object'].slug:
p = Product.objects.get(slug=i)
if p not in retval['ranee']:
retval['ranee'].append(p)
#import pdb;pdb.set_trace()
if retval['ranee']:
retval['ranee'] = retval['ranee'][::-1][:4]
return retval
def post(self, request, *args, **kwargs):
self.category = self._get_full_category(kwargs['categories'])
super(ProductView, self).get(request, args, kwargs)
context_data = self.get_context_data()
# context_data['category'] = self.category
form = ProductFeedbackForm(request.POST or None)
if form.is_valid():
obj = form.save(commit=False)
obj.product = self.object
obj.save()
messages.success(self.request, 'Ваш отзыв успешно опубликован. Спасибо!')
mail_managers('Оставили отзыв о товаре', 'Смотреть в админке')
return redirect(self.object.get_absolute_url())
else:
return self.render_to_response(context_data)
class CartAddView(RedirectView):
def dispatch(self, request, *args, **kwargs):
retval = super(CartAddView, self).dispatch(request, args, kwargs)
cart = Cart(self.request)
try:
item_variant = ProductVariation.objects.get(
pk=self.request.GET.get('pk'))
except ProductVariation.DoesNotExist:
return redirect('/')
count = self.request.GET.get('count')
# messages.success(
# self.request, """Товар успешно добавлен в корзину!
# Вы можете перейти к оформлению заказа,
# либо продолжить выбор товаров.
# <a href='/store/cart/'>Открыть корзину...</a>""")
cart.add_item(CartItem(item_variant, count))
return retval
def get_redirect_url(self, *args, **kwargs):
from django.core.urlresolvers import reverse
return reverse('store_cart_detail')
class CartRemoveView(RedirectView):
def dispatch(self, request, *args, **kwargs):
retval = super(CartRemoveView, self).dispatch(request, args, kwargs)
cart = Cart(self.request)
item_id = self.request.GET.get('id')
cart.remove_item(item_id)
return retval
def get_redirect_url(self, *args, **kwargs):
return '/store/cart/'
class CartDetailView(TemplateView):
template_name = 'cart_detail.jinja'
def get_context_data(self, **kwargs):
from .models import KAZPOST_CITIES
retval = super(CartDetailView, self).get_context_data()
retval['cart'] = Cart(self.request)
retval['form'] = OrderForm(self.request.POST or None)
retval['alemtat_cities'] = alemtat_get_cities_tuple()
retval['alemtat_services'] = alemtat_get_services_tuple()
retval['kazpost_cities'] = KAZPOST_CITIES
# retval['form_delivs'] = DelivsForm()
return retval
def post(self, request, *args, **kwargs):
cart = Cart(self.request)
cart.update_items()
if 'order_next' in self.request.POST:
deliv_service = request.POST['deliv_service']
form = OrderForm(self.request.POST)
if form.is_valid():
order = form.save(commit=False)
json_items = map(lambda items: {items.item.pk: items.count}, cart.items)
order.items = str(list(json_items))
cart = Cart(request)
order.phone = normalize_phone(order.phone)
order.deliv_service = deliv_service
if deliv_service == 'alemtat':
a = AlemTat()
order.city = request.POST['city']
order.deliv_type = request.POST['deliv_type']
order_amount = dict(a.get_amount(
order.city,
len(cart.items),
cart.weight,
order.deliv_type,
))
order.amount = order_amount['AmountPlusFSAmount'] + cart.total
order.address = request.POST['alemtat_address']
elif deliv_service == 'kazpost':
amount = get_kazpost_tarif(cart.weight, request.POST['kazpost_city'])
order.amount = int(amount) + cart.total
order.kazpost_city = int(request.POST['kazpost_city'])
order.address = request.POST['kazpost_address']
profile = None
try:
profile = Profile.objects.get(phone=normalize_phone(order.phone))
#profile.set_password(settings.PROFILE_TEMP_PASSWORD)
#profile.save()
send_email(profile, template='mail/order.jinja')
except:
from random import randint
import requests
password = randint(10000000, 99999999)
profile = Profile.objects.create(
phone=normalize_phone(order.phone),
email=order.email,
first_name=order.first_name,
last_name=order.last_name,
)
profile.set_password(password)
profile.save()
phone = normalize_phone(order.phone)
params = dict(
login='Jango.kz',
psw='AcEMXtLGz042Fc1ZJUSl',
phones='7{}'.format(phone),
mes='Batiskaf.kz - Vash parol: {}'.format(password)
)
requests.get('http://smsc.ru/sys/send.php', params=params)
send_email(profile, template='mail/registration.jinja')
user = authenticate(username=profile.phone, password=password)
if user.is_active:
login(request, user)
order.profile = profile
order.save()
mail_managers('Оформили заказ', 'Смотреть в админке')
payment_type = request.POST.get('payment_type', 'card')
if payment_type == 'card':
return redirect('/order/{}/kkb/'.format(order.pk))
return redirect('/order/{}/print/'.format(order.pk))
else:
return self.render_to_response(self.get_context_data())
return redirect(self.request.path)
def get_order_amount(request):
retval = None
a = AlemTat()
cart = Cart(request)
retval = dict(a.get_amount(
request.GET['city'],
len(cart.items),
cart.weight,
request.GET['deliv'],
))
return JsonResponse(retval)
def get_kazpost_tarif(weight, to):
import requests
import re
url="http://rates.kazpost.kz/postratesws/postratesws.wsdl"
#headers = {'content-type': 'application/soap+xml'}
headers = {'content-type': 'text/xml'}
body = """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pos="http://webservices.kazpost.kz/postratesws">
<soapenv:Header/>
<soapenv:Body>
<pos:GetPostRateRequest>
<pos:MailInfo>
<pos:Product>7</pos:Product>
<pos:MailCat>2</pos:MailCat>
<pos:SendMethod>2</pos:SendMethod>
<pos:Weight>{}</pos:Weight>
<pos:From>13</pos:From>
<pos:To>{}</pos:To>
<pos:SpecMarks/>
<pos:InCity/>
<pos:ExpressDlv/>
<pos:Size/>
<pos:DeclaredValue/>
</pos:MailInfo>
</pos:GetPostRateRequest>
</soapenv:Body>
</soapenv:Envelope>"""
body = body.format(weight*1000, to)
try:
response = requests.post(url, data=body, headers=headers)
m = re.search(r'<ns2:PostRate>(\d+)</ns2:PostRate>', response.text)
return m.group(1)
except:
return 0
def get_order_kazpost_amount(request):
retval = None
cart = Cart(request)
retval = dict(amount=get_kazpost_tarif(cart.weight, request.GET['city']))
return JsonResponse(retval)
def order_view(request, order):
order = get_object_or_404(OrderData, pk=order)
c = dict(order=order, date=datetime.now())
return render(request, 'order_ok.jinja', c)
def order_print(request, order):
order = get_object_or_404(OrderData, pk=order)
c = dict(order=order, date=datetime.now())
return render(request, 'order_print.jinja', c)
def order_kkb(request, order):
order = get_object_or_404(OrderData, pk=order)
cart = Cart(request)
context = kkb.get_context(order.pk, amount=order.amount, b64=True)
c_appendix = dict(items=cart.items, deliv_price=order.amount - cart.total)
render_appendix = render_to_string('kkb/appendix.xml', c_appendix)
appendix = base64.b64encode(
bytes(render_appendix, 'utf-8')
).decode('utf-8')
c = dict(order=order, context=context, appendix=appendix)
return render(request, 'kkb.jinja', c)
def kkb_result(request):
mail_admins('POST', str(request.POST))
response = request.POST['response']
result = kkb.postlink(response)
if result.status:
order = OrderData.objects.get(pk=int(result.data['ORDER_ID']))
order.status = 1
order.save()
mail_managers('Оплатили заказ картой', 'Заказ №{}'.format(order.pk))
else:
print(result.message)
return render(request, 'kkb_ok.jinja')
class ProductSitemap(Sitemap):
changefreq = "daily"
priority = 0.8
def items(self):
return Product.objects.all()
class CategorySitemap(Sitemap):
changefreq = "daily"
priority = 0.6
def items(self):
return Category.objects.all()