parent
5c1bf22146
commit
39c36eb223
19 changed files with 465 additions and 33 deletions
@ -1,4 +1,38 @@ |
|||||||
from django import forms |
from django import forms |
||||||
|
from accounts.models import Profile |
||||||
|
from random import randint |
||||||
|
from accounts.utils import normalize_phone |
||||||
|
|
||||||
|
|
||||||
class LoginForm(forms.Form): |
class LoginForm(forms.Form): |
||||||
phone = forms.CharField(label='Телефон', max_length=15) |
phone = forms.CharField(label='Номер мобильного телефона', max_length=45, required=True) |
||||||
|
|
||||||
|
def clean_phone(self): |
||||||
|
data = normalize_phone(self.cleaned_data['phone']) |
||||||
|
try: |
||||||
|
profile = Profile.objects.get(phone=data) |
||||||
|
profile.temp_password = randint(1000000, 9999999) |
||||||
|
self.temp_password = profile.temp_password |
||||||
|
profile.save() |
||||||
|
except Profile.DoesNotExist: |
||||||
|
raise forms.ValidationError("Вы еще не совершали покупки в нашем магазине") |
||||||
|
return data |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LoginSmsForm(forms.Form): |
||||||
|
sms = forms.IntegerField(label='Одноразовый пароль', required=True) |
||||||
|
|
||||||
|
def clean_sms(self): |
||||||
|
data = self.cleaned_data['sms'] |
||||||
|
phone = normalize_phone(self.phone) |
||||||
|
try: |
||||||
|
profile = Profile.objects.get(phone=phone, temp_password=data) |
||||||
|
self.profile = profile |
||||||
|
#profile.temp_password = randint(1000000, 9999999) |
||||||
|
#self.temp_password = profile.temp_password |
||||||
|
#profile.save() |
||||||
|
except Profile.DoesNotExist: |
||||||
|
raise forms.ValidationError("Неверный одноразовый пароль") |
||||||
|
return data |
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import models, migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('accounts', '0002_auto_20150611_2306'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='profile', |
||||||
|
name='temp_password', |
||||||
|
field=models.IntegerField(blank=True, null=True, verbose_name='Одноразовый пароль', default=None), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='profile', |
||||||
|
name='phone', |
||||||
|
field=models.CharField(verbose_name='Номер мобильного телефона', max_length=15, unique=True, db_index=True), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
import re |
||||||
|
|
||||||
|
def normalize_phone(phone): |
||||||
|
retval = re.sub("\D", "", phone) |
||||||
|
if len(retval) > 10: |
||||||
|
retval = retval[len(retval)-10:] |
||||||
|
return retval |
||||||
@ -1,7 +1,61 @@ |
|||||||
from django.shortcuts import render |
from django.contrib.auth.decorators import login_required |
||||||
|
from django.shortcuts import render, get_object_or_404, redirect |
||||||
from django.views.generic import FormView |
from django.views.generic import FormView |
||||||
from .forms import * |
from .forms import * |
||||||
|
from store.models import OrderData |
||||||
|
from django.contrib.auth import logout, authenticate, login |
||||||
|
from .utils import normalize_phone |
||||||
|
from random import randint |
||||||
|
import requests |
||||||
|
from django.conf import settings |
||||||
|
|
||||||
class LoginView(FormView): |
class LoginView(FormView): |
||||||
form_class = LoginForm |
form_class = LoginForm |
||||||
template_name = 'accounts/login.jinja' |
template_name = 'accounts/login.jinja' |
||||||
|
|
||||||
|
def login_view(request): |
||||||
|
form = LoginForm(request.POST or None) |
||||||
|
if form.is_valid(): |
||||||
|
phone = form.cleaned_data['phone'] |
||||||
|
params = dict( |
||||||
|
login='Jango.kz', |
||||||
|
psw='AcEMXtLGz042Fc1ZJUSl', |
||||||
|
phones='7{}'.format(phone), |
||||||
|
mes='Batiskaf.kz odnorazoviy parol: {}'.format(form.temp_password) |
||||||
|
) |
||||||
|
requests.get('http://smsc.ru/sys/send.php', params=params) |
||||||
|
return redirect('/account/login/sms/?phone='+phone) |
||||||
|
c = dict(form=form) |
||||||
|
return render(request, 'accounts/login.jinja', c) |
||||||
|
|
||||||
|
def login_sms_view(request): |
||||||
|
form = LoginSmsForm(request.POST or None) |
||||||
|
phone = request.GET.get('phone', None) |
||||||
|
form.phone = phone |
||||||
|
if form.is_valid(): |
||||||
|
profile = form.profile |
||||||
|
profile.set_password(settings.PROFILE_TEMP_PASSWORD) |
||||||
|
profile.save() |
||||||
|
user = authenticate(username=profile.phone, password=settings.PROFILE_TEMP_PASSWORD) |
||||||
|
if user.is_active: |
||||||
|
login(request, user) |
||||||
|
return redirect('/account/') |
||||||
|
|
||||||
|
c = dict(form=form) |
||||||
|
return render(request, 'accounts/login_sms.jinja', c) |
||||||
|
|
||||||
|
@login_required |
||||||
|
def account_index(request): |
||||||
|
return render(request, 'accounts/index.jinja') |
||||||
|
|
||||||
|
@login_required |
||||||
|
def account_logout(request): |
||||||
|
logout(request) |
||||||
|
return redirect('/') |
||||||
|
|
||||||
|
@login_required |
||||||
|
def order_detail(request, pk): |
||||||
|
order = get_object_or_404(OrderData, pk=pk, profile=request.user) |
||||||
|
c = dict(order=order) |
||||||
|
return render(request, 'accounts/order_detail.jinja', c) |
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,52 @@ |
|||||||
|
{% extends 'base.jinja' %} |
||||||
|
{% block title %} |
||||||
|
Личный кабинет |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block content %} |
||||||
|
<div class=" breadcrumbs"> |
||||||
|
<ol class="breadcrumb breadcrumb-arrow"> |
||||||
|
<li><a href="/">Главная</a></li> |
||||||
|
|
||||||
|
<li class="active"><span>Личный кабинет</span></li> |
||||||
|
|
||||||
|
</ol> |
||||||
|
</div> |
||||||
|
<h2>Ваши заказы, {{ request.user.first_name }}:</h2> |
||||||
|
|
||||||
|
<br/> |
||||||
|
<div class="row"> |
||||||
|
<div class="col-xs-12"> |
||||||
|
<div class="panel"> |
||||||
|
<table class="table table-hover table-bordered"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Номер заказа</th> |
||||||
|
<th>Дата</th> |
||||||
|
<th>Кому/Куда</th> |
||||||
|
<th>Способ доставки</th> |
||||||
|
<th>Сумма</th> |
||||||
|
<th>Статус</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for order in request.user.orders.all() %} |
||||||
|
|
||||||
|
<tr> |
||||||
|
<td>{{ order.pk }}</td> |
||||||
|
<td>{{ order.created.strftime('%d.%m.%Y') }}</td> |
||||||
|
<td><a href="/account/order/{{ order.pk }}/"><b>{{ order.first_name }} {{ order.last_name }}</b><br/> |
||||||
|
г. {{ order.get_city_display() }}<br/> |
||||||
|
{{ order.address }}</a></td> |
||||||
|
<td>{{ order.get_deliv_type_display() }}</td> |
||||||
|
<td>{{ order.amount }}</td> |
||||||
|
<td>{{ order.get_status_display() }}</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
@ -1,4 +1,36 @@ |
|||||||
{% extends 'base.jinja' %} |
{% extends 'base.jinja' %} |
||||||
|
{% block title %} |
||||||
|
Вход в личный кабинет |
||||||
|
{% endblock %} |
||||||
{% block content %} |
{% block content %} |
||||||
{{ form }} |
<div class=" breadcrumbs"> |
||||||
|
<ol class="breadcrumb breadcrumb-arrow"> |
||||||
|
<li><a href="/">Главная</a></li> |
||||||
|
|
||||||
|
<li class="active"><span>Вход в личный кабинет</span></li> |
||||||
|
|
||||||
|
</ol> |
||||||
|
</div> |
||||||
|
<h2>Вход в личный кабинет</h2><br/> |
||||||
|
<div class="well well-large"> |
||||||
|
<div class="alert alert-info alert-dismissable"> |
||||||
|
<h4>Введите номер телефона</h4> |
||||||
|
|
||||||
|
<p>Если вы уже совершали покупки в нашем интернет-магазине, на ваш номер телефона будет отправлено SMS-сообщение с одноразовым паролем для входа.</p> |
||||||
|
|
||||||
|
|
||||||
|
</div> |
||||||
|
<div class="row"> |
||||||
|
<div class="login-form col-xs-6 col-xs-offset-3"> |
||||||
|
<form action="" class="form" method="post"><input type="hidden" name="csrfmiddlewaretoken" |
||||||
|
value="{{ csrf_token }}"> |
||||||
|
{{ form|bootstrap }} |
||||||
|
<div class="form-group text-left"> |
||||||
|
<button type="submit" name="login-send" class="btn btn-primary">Далее |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
{% endblock %} |
{% endblock %} |
||||||
|
|||||||
@ -0,0 +1,37 @@ |
|||||||
|
{% extends 'base.jinja' %} |
||||||
|
{% block title %} |
||||||
|
Ввод одноразового пароля |
||||||
|
{% endblock %} |
||||||
|
{% block content %} |
||||||
|
<div class=" breadcrumbs"> |
||||||
|
<ol class="breadcrumb breadcrumb-arrow"> |
||||||
|
<li><a href="/">Главная</a></li> |
||||||
|
|
||||||
|
<li><a href="/account/login/">Вход в личный кабинет</a></li> |
||||||
|
<li class="active"><span>Ввод одноразового пароля</span></li> |
||||||
|
|
||||||
|
</ol> |
||||||
|
</div> |
||||||
|
<h2>Ввод одноразового пароля</h2><br/> |
||||||
|
<div class="well well-large"> |
||||||
|
<div class="alert alert-info alert-dismissable"> |
||||||
|
<h4>Проверьте телефон</h4> |
||||||
|
|
||||||
|
<p>На Ваш номер было отправлено SMS-сообщение с одноразовым паролем для входа. Введите его в поле ниже.</p> |
||||||
|
|
||||||
|
|
||||||
|
</div> |
||||||
|
<div class="row"> |
||||||
|
<div class="sms-form col-xs-6 col-xs-offset-3"> |
||||||
|
<form action="" class="form" method="post"><input type="hidden" name="csrfmiddlewaretoken" |
||||||
|
value="{{ csrf_token }}"> |
||||||
|
{{ form|bootstrap }} |
||||||
|
<div class="form-group text-left"> |
||||||
|
<button type="submit" name="sms-send" class="btn btn-primary">Войти |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
{% extends 'base.jinja' %} |
||||||
|
{% block title %} |
||||||
|
Заказ номер {{ order.pk }} |
||||||
|
{% endblock %} |
||||||
|
{% block content %} |
||||||
|
<div class=" breadcrumbs"> |
||||||
|
<ol class="breadcrumb breadcrumb-arrow"> |
||||||
|
<li><a href="/">Главная</a></li> |
||||||
|
|
||||||
|
<li><a href="/account/">Личный кабинет</a></li> |
||||||
|
<li class="active"><span>Заказ номер {{ order.pk }}</span></li> |
||||||
|
|
||||||
|
</ol> |
||||||
|
</div> |
||||||
|
<h2>Заказ №{{ order.pk }}</h2> |
||||||
|
|
||||||
|
<br/> |
||||||
|
<div class="row"> |
||||||
|
<div class="panel "> |
||||||
|
<table class="table table-hover table-bordered"> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th>Фото</th> |
||||||
|
<th>Товар</th> |
||||||
|
<th>Стоимость</th> |
||||||
|
<th>Количество</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
{% for item, count in order.get_items() %} |
||||||
|
<tr> |
||||||
|
<td class="text-center table-cart-image"> |
||||||
|
{% set im = item.product.main_image()|thumbnail("80x80") %} |
||||||
|
<a href="{{ item.product.get_absolute_url() }}"><img src="/static/{{ im.url }}" |
||||||
|
alt="{{ item.product.title }}" |
||||||
|
title="{{ item.product.title }}" |
||||||
|
class="img-thumbnail"/></a> |
||||||
|
</td> |
||||||
|
<td> |
||||||
|
<a href="{{ item.product.get_absolute_url() }}">{{ item.product.title }}</a><br/> |
||||||
|
<em>{{ item.variation }}</em> |
||||||
|
</td> |
||||||
|
<td class="text-right info">{{ item.get_price() }} ₸</td> |
||||||
|
<td class="text-right">{{ count }} шт. |
||||||
|
|
||||||
|
</td> |
||||||
|
</tr> |
||||||
|
{% endfor %} |
||||||
|
|
||||||
|
</tbody> |
||||||
|
</table> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
{% endblock %} |
||||||
|
|
||||||
@ -0,0 +1,21 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import models, migrations |
||||||
|
from django.conf import settings |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||||
|
('store', '0018_auto_20150615_1130'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='orderdata', |
||||||
|
name='profile', |
||||||
|
field=models.ForeignKey(null=True, default=None, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import models, migrations |
||||||
|
from django.conf import settings |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('store', '0019_orderdata_profile'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AlterField( |
||||||
|
model_name='orderdata', |
||||||
|
name='phone', |
||||||
|
field=models.CharField(verbose_name='Номер мобильного телефона', max_length=15), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='orderdata', |
||||||
|
name='profile', |
||||||
|
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='orders', null=True, default=None), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
# -*- coding: utf-8 -*- |
||||||
|
from __future__ import unicode_literals |
||||||
|
|
||||||
|
from django.db import models, migrations |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('store', '0020_auto_20150616_2302'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='orderdata', |
||||||
|
name='status', |
||||||
|
field=models.IntegerField(verbose_name='Статус', choices=[(0, 'Ожидает оплаты'), (1, 'Формирование посылки'), (2, 'Ожидает отправки'), (3, 'Отправлено')], default=0), |
||||||
|
), |
||||||
|
] |
||||||
Loading…
Reference in new issue