Compare commits
5 Commits
87f67aa24a
...
feature/su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15c9d589fe | ||
|
|
fa116c08c1 | ||
|
|
4f9129e718 | ||
|
|
df45f3a704 | ||
|
|
90ef093fca |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -414,8 +414,5 @@ fabric.properties
|
|||||||
|
|
||||||
# Android studio 3.1+ serialized cache file
|
# Android studio 3.1+ serialized cache file
|
||||||
.idea/caches/build_file_checksums.ser
|
.idea/caches/build_file_checksums.ser
|
||||||
|
celerybeat-schedule.db
|
||||||
# packages for node
|
|
||||||
package.json
|
|
||||||
package-lock.json
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ def get_articles_block_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = request.POST.dict()
|
data = request.POST.dict()
|
||||||
@@ -45,9 +42,6 @@ def get_articles_block_ajax(request):
|
|||||||
# 'form': RouteForm(initial=data)
|
# 'form': RouteForm(initial=data)
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from datetime import datetime, date
|
|||||||
from django.http import Http404, HttpResponse
|
from django.http import Http404, HttpResponse
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
from .funcs import *
|
from .funcs import *
|
||||||
from GeneralApp.funcs import get_inter_http_response
|
from GeneralApp.funcs import get_inter_http_respose
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
# from django.contrib.auth.decorators import login_required
|
# from django.contrib.auth.decorators import login_required
|
||||||
@@ -85,14 +85,14 @@ def ArticlesPageView(request, year=None):
|
|||||||
Dict = get_articles(art_kwargs=kwargs)
|
Dict = get_articles(art_kwargs=kwargs)
|
||||||
Dict.update({
|
Dict.update({
|
||||||
'page': {
|
'page': {
|
||||||
'title': _('Новости сервиса доставки посылок | TripWB'),
|
'title': _('Страница списка новостей'),
|
||||||
'description': _('Обновления, полезные статьи и свежие новости от TripWB ✓ Актуальные новости в мире доставок по всему СНГ ➡️ Следите за нашими новостями'),
|
'description': _('Все новости сайта tripwb.com'),
|
||||||
'keywords': _('Все новости сайта tripwb.com'),
|
'keywords': _('Все новости сайта tripwb.com'),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t = loader.get_template('pages/p_articles.html')
|
t = loader.get_template('pages/p_articles.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ def UserPageView(request, page_url):
|
|||||||
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_user_page.html')
|
t = loader.get_template('pages/p_user_page.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
@@ -155,5 +155,5 @@ def ArticlesOnePageView(request, art_url):
|
|||||||
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_article.html')
|
t = loader.get_template('pages/p_article.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|||||||
@@ -97,14 +97,12 @@ class Admin_User(UserAdmin):
|
|||||||
save_on_top = True
|
save_on_top = True
|
||||||
|
|
||||||
list_display = ['id', 'last_name', 'first_name', 'mailing_on', 'email', 'is_staff',
|
list_display = ['id', 'last_name', 'first_name', 'mailing_on', 'email', 'is_staff',
|
||||||
'is_active', 'date_joined', 'last_login']
|
'is_active']
|
||||||
list_editable = ['is_staff', 'is_active']
|
list_editable = ['is_staff', 'is_active']
|
||||||
list_display_links = ['first_name', 'last_name', 'email']
|
list_display_links = ['first_name', 'last_name', 'email']
|
||||||
search_fields = ['first_name', 'last_name', 'email']
|
search_fields = ['first_name', 'last_name', 'email']
|
||||||
|
|
||||||
readonly_fields = ['date_joined', 'last_login']
|
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active']
|
||||||
|
|
||||||
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active', 'date_joined', 'last_login']
|
|
||||||
|
|
||||||
inlines = (Admin_ProfileInline,)
|
inlines = (Admin_ProfileInline,)
|
||||||
# actions = ['del_all_temp_users', ]
|
# actions = ['del_all_temp_users', ]
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class RegistrationForm(forms.Form):
|
|||||||
email = forms.EmailField()
|
email = forms.EmailField()
|
||||||
password = forms.CharField(widget=forms.PasswordInput())
|
password = forms.CharField(widget=forms.PasswordInput())
|
||||||
confirm_password = forms.CharField(widget=forms.PasswordInput())
|
confirm_password = forms.CharField(widget=forms.PasswordInput())
|
||||||
tel = forms.CharField(required=False)
|
tel = forms.CharField()
|
||||||
agreement = forms.BooleanField(initial=False, required=True)
|
agreement = forms.BooleanField(initial=False, required=True)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
from django.http import QueryDict
|
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_timezone_Dict(user, request=None):
|
def get_user_timezone_Dict(user, request=None):
|
||||||
@@ -32,12 +30,10 @@ def get_profile_page_content_html(request, page_name, data):
|
|||||||
if page_name == 'chat':
|
if page_name == 'chat':
|
||||||
from ChatServiceApp.funcs import get_chat_page_content_html
|
from ChatServiceApp.funcs import get_chat_page_content_html
|
||||||
return get_chat_page_content_html(request, data)
|
return get_chat_page_content_html(request, data)
|
||||||
elif (page_name == 'create_route_for_customer' and
|
elif page_name == 'create_route_for_customer':
|
||||||
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
|
|
||||||
from RoutesApp.funcs import get_profile_new_route_page_html
|
from RoutesApp.funcs import get_profile_new_route_page_html
|
||||||
return get_profile_new_route_page_html(request, {'owner_type': 'customer'})
|
return get_profile_new_route_page_html(request, {'owner_type': 'customer'})
|
||||||
elif (page_name == 'create_route_for_mover' and
|
elif page_name == 'create_route_for_mover':
|
||||||
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
|
|
||||||
from RoutesApp.funcs import get_profile_new_route_page_html
|
from RoutesApp.funcs import get_profile_new_route_page_html
|
||||||
return get_profile_new_route_page_html(request, {'owner_type': 'mover'})
|
return get_profile_new_route_page_html(request, {'owner_type': 'mover'})
|
||||||
elif page_name == 'my_routes':
|
elif page_name == 'my_routes':
|
||||||
@@ -46,9 +42,8 @@ def get_profile_page_content_html(request, page_name, data):
|
|||||||
elif page_name == 'support':
|
elif page_name == 'support':
|
||||||
return get_profile_support_page_content_html(request, data)
|
return get_profile_support_page_content_html(request, data)
|
||||||
elif page_name == 'my_subscribe':
|
elif page_name == 'my_subscribe':
|
||||||
from SubscribesApp.funcs import get_profile_subscribe_page_content_Dict
|
from SubscribesApp.funcs import get_profile_subscribe_page_content_html
|
||||||
res = get_profile_subscribe_page_content_Dict(request, check_orders_required=True)
|
return get_profile_subscribe_page_content_html(request)
|
||||||
return res['html']
|
|
||||||
elif page_name == 'change_profile':
|
elif page_name == 'change_profile':
|
||||||
return get_profile_change_page_content_html(request)
|
return get_profile_change_page_content_html(request)
|
||||||
elif page_name == 'dashboard':
|
elif page_name == 'dashboard':
|
||||||
@@ -57,7 +52,7 @@ def get_profile_page_content_html(request, page_name, data):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_profile_change_page_content_html(request, data=None):
|
def get_profile_change_page_content_html(request):
|
||||||
|
|
||||||
init_Dict = {
|
init_Dict = {
|
||||||
'firstname': request.user.first_name,
|
'firstname': request.user.first_name,
|
||||||
@@ -67,25 +62,6 @@ def get_profile_change_page_content_html(request, data=None):
|
|||||||
'country': request.user.user_profile.country,
|
'country': request.user.user_profile.country,
|
||||||
'city': request.user.user_profile.city,
|
'city': request.user.user_profile.city,
|
||||||
}
|
}
|
||||||
|
|
||||||
if data:
|
|
||||||
if type(data) == QueryDict:
|
|
||||||
data = data.dict()
|
|
||||||
init_Dict.update(data)
|
|
||||||
# if 'firstname' in data:
|
|
||||||
# init_Dict.update({'first_name': data['firstname']})
|
|
||||||
# if 'lastname' in data:
|
|
||||||
# init_Dict.update({'last_name': data['lastname']})
|
|
||||||
# if 'email' in data:
|
|
||||||
# init_Dict.update({'email': data['email']})
|
|
||||||
# init_Dict.update({'username': data['email']})
|
|
||||||
# if 'country' in data:
|
|
||||||
# init_Dict.update({'country': data['country']})
|
|
||||||
# if 'city' in data:
|
|
||||||
# init_Dict.update({'city': data['city']})
|
|
||||||
# if 'tel' in data:
|
|
||||||
# init_Dict.update({'tel': data['tel']})
|
|
||||||
|
|
||||||
from .forms import RegistrationForm
|
from .forms import RegistrationForm
|
||||||
form = RegistrationForm(initial=init_Dict)
|
form = RegistrationForm(initial=init_Dict)
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ urlpatterns = [
|
|||||||
|
|
||||||
path('support_tickets/', support_tickets_ajax, name='support_tickets_ajax'),
|
path('support_tickets/', support_tickets_ajax, name='support_tickets_ajax'),
|
||||||
|
|
||||||
path('password_recovery/', password_recovery_ajax, name='password_recovery_ajax'),
|
|
||||||
path('password_recovery_confirm/', password_recovery_confirm_ajax, name='password_recovery_confirm_ajax'),
|
|
||||||
|
|
||||||
path('change_profile/', change_profile_ajax, name='change_profile_ajax'),
|
path('change_profile/', change_profile_ajax, name='change_profile_ajax'),
|
||||||
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),
|
path('change_profile_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ from django.core.files import File
|
|||||||
import base64
|
import base64
|
||||||
from django.core.validators import validate_email
|
from django.core.validators import validate_email
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
|
|
||||||
# @login_required()#login_url='/profile/login/')
|
|
||||||
|
# @login_required(login_url='/profile/login/')
|
||||||
# def subscribe_ajax(request):
|
# def subscribe_ajax(request):
|
||||||
# if request.method != 'POST':
|
# if request.method != 'POST':
|
||||||
# raise Http404
|
# raise Http404
|
||||||
@@ -31,132 +31,11 @@ from GeneralApp.funcs import get_and_set_lang
|
|||||||
# html = render_to_string('blocks/profile/b_subscribe.html', Dict, request=request)
|
# html = render_to_string('blocks/profile/b_subscribe.html', Dict, request=request)
|
||||||
# return JsonResponse({'html': html}, status=200)
|
# return JsonResponse({'html': html}, status=200)
|
||||||
|
|
||||||
def password_recovery_confirm_ajax(request):
|
|
||||||
if request.method != 'POST':
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
if not 'pass' in request.POST or not 'pass_confirm' in request.POST or not 'user_id' in request.POST:
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
if not request.POST['pass'] or request.POST['pass'] != request.POST['pass_confirm']:
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'error',
|
|
||||||
'error': _('Пароли не совпадают')
|
|
||||||
}, status=400)
|
|
||||||
|
|
||||||
user = User.objects.get(id=request.POST['user_id'])
|
|
||||||
user.set_password(request.POST['pass'])
|
|
||||||
user.user_profile.authMailCode = None
|
|
||||||
user.user_profile.save(update_fields=['authMailCode'])
|
|
||||||
user.is_active = True
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'success',
|
|
||||||
'message': _('Пароль был успешно изменен')
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'error',
|
|
||||||
'error': str(e)
|
|
||||||
}, status=400)
|
|
||||||
|
|
||||||
def password_recovery_ajax(request):
|
|
||||||
if request.method != 'POST':
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
|
||||||
email = request.POST['email']
|
|
||||||
|
|
||||||
try:
|
|
||||||
user = User.objects.get(email=email)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
msg = _('Пользователь с указанным email не зарегистрирован на сайте')
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'error',
|
|
||||||
'error': msg
|
|
||||||
}, status=400)
|
|
||||||
|
|
||||||
user.user_profile.authMailCode = uuid1().hex
|
|
||||||
user.user_profile.save(update_fields=['authMailCode'])
|
|
||||||
|
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
|
||||||
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
|
||||||
|
|
||||||
subject = _('Изменение пароля учетной записи на сайте tripwb.com')
|
|
||||||
|
|
||||||
mail_txt = _('Вы получили это письмо потому что '
|
|
||||||
'был произведен запрос на изменение пароля '
|
|
||||||
'для данного email на сайте tripwb.com.<br>'
|
|
||||||
'<br>'
|
|
||||||
'Если Вы не выполняли запрос - просто проигнорируйте это письмо.<br><br>'
|
|
||||||
'Если же это были Вы и Вам требуется изменить пароль от учетной записи - '
|
|
||||||
'перейдите по ссылке, указанной ниже.<br><br>')
|
|
||||||
link = sets["domain"] + f'/profile/reset_password/{str(user.id)}/{user.user_profile.authMailCode}/'
|
|
||||||
link_str = f'<a href="{link}">ИЗМЕНИТЬ ПАРОЛЬ</a><br><br>'
|
|
||||||
|
|
||||||
sign_txt = _('Спасибо за то, что вы с нами!<br>'
|
|
||||||
'С уважением,<br>'
|
|
||||||
'Команда Trip With Bonus.<br>')
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
|
||||||
'project_name': sets['project_name'],
|
|
||||||
'message_title': subject,
|
|
||||||
'message_text': f'<p style="padding-left: 20px; line-height: 30px;">'
|
|
||||||
f'{mail_txt}'
|
|
||||||
f'{link_str}'
|
|
||||||
f'{sign_txt}'
|
|
||||||
f'</p>'
|
|
||||||
}
|
|
||||||
|
|
||||||
html = render_to_string('mail/m_request_offer.html', Dict, request)
|
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
|
||||||
mail_sets = get_mail_send_options()
|
|
||||||
to = [email]
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
to = ['web@syncsystems.net']
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'sended',
|
|
||||||
'message': _('На email') + ' ' + email + ' '
|
|
||||||
+ _('отправлено письмо с инструкциями для восстановления пароля. Если не пришло письмо, проверьте папку СПАМ')
|
|
||||||
})
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return JsonResponse({
|
|
||||||
'status': 'error',
|
|
||||||
'error': str(e)
|
|
||||||
}, status=400)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def mailing_subscribe_ajax(request):
|
def mailing_subscribe_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
email = request.POST['email']
|
email = request.POST['email']
|
||||||
@@ -166,13 +45,11 @@ def mailing_subscribe_ajax(request):
|
|||||||
user.user_profile.mailing_on = True
|
user.user_profile.mailing_on = True
|
||||||
user.user_profile.save(update_fields=['mailing_on'])
|
user.user_profile.save(update_fields=['mailing_on'])
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse({
|
||||||
res_Dict = {
|
|
||||||
'status': 'sended',
|
'status': 'sended',
|
||||||
'del_form': True,
|
'del_form': True,
|
||||||
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
|
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
|
||||||
}
|
})
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
try:
|
try:
|
||||||
@@ -185,14 +62,11 @@ def mailing_subscribe_ajax(request):
|
|||||||
else:
|
else:
|
||||||
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
|
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse({
|
||||||
res_Dict = {
|
|
||||||
'status': 'sended',
|
'status': 'sended',
|
||||||
'redirect_url': redirect_url,
|
'redirect_url': redirect_url,
|
||||||
'email': email
|
'email': email
|
||||||
}
|
})
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -206,8 +80,6 @@ def send_message_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = request.POST
|
data = request.POST
|
||||||
@@ -314,14 +186,7 @@ def send_message_ajax(request):
|
|||||||
html = render_to_string('mail/m_request_offer.html', Dict, request)
|
html = render_to_string('mail/m_request_offer.html', Dict, request)
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
||||||
mail_sets = get_mail_send_options()
|
mail_sets = get_mail_send_options()
|
||||||
to = [mail_sets['sender_email']]
|
to = [mail_sets['sender_email'], 'web@syncsystems.net']
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
to = ['web@syncsystems.net']
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
res = admin_send_mail_by_SMTPlib(
|
||||||
mail_sets,
|
mail_sets,
|
||||||
subject=subject,
|
subject=subject,
|
||||||
@@ -331,14 +196,10 @@ def send_message_ajax(request):
|
|||||||
|
|
||||||
html = render_to_string('widgets/w_msg_send_success.html', Dict, request)
|
html = render_to_string('widgets/w_msg_send_success.html', Dict, request)
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse({
|
||||||
res_Dict = {
|
|
||||||
'status': 'sended',
|
'status': 'sended',
|
||||||
'html': html
|
'html': html
|
||||||
}
|
})
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
@@ -346,13 +207,11 @@ def send_message_ajax(request):
|
|||||||
}, status=400)
|
}, status=400)
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def chats_ajax(request):
|
def chats_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
from ChatServiceApp.funcs import get_chat_receivers_for_user, get_msgs_for_chat_w_users
|
from ChatServiceApp.funcs import get_chat_receivers_for_user, get_msgs_for_chat_w_users
|
||||||
|
|
||||||
receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)
|
receivers, unread_msgs_count = get_chat_receivers_for_user(request.user)
|
||||||
@@ -376,28 +235,19 @@ def chats_ajax(request):
|
|||||||
Dict.update(get_user_timezone_Dict(request.user, request=request))
|
Dict.update(get_user_timezone_Dict(request.user, request=request))
|
||||||
|
|
||||||
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
|
html = render_to_string('blocks/profile/b_chats.html', Dict, request=request)
|
||||||
|
return JsonResponse({'html': html}, status=200)
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
@login_required(login_url='/profile/login/')
|
||||||
res_Dict = {'html': html}
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
|
||||||
def support_tickets_ajax(request):
|
def support_tickets_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
html = get_profile_support_page_content_html(request)
|
html = get_profile_support_page_content_html(request)
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = {'html': html}
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def change_avatar_confirm_ajax(request):
|
def change_avatar_confirm_ajax(request):
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.core.exceptions import RequestDataTooBig
|
from django.core.exceptions import RequestDataTooBig
|
||||||
@@ -405,8 +255,6 @@ def change_avatar_confirm_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
file_data = json.loads(request.body)
|
file_data = json.loads(request.body)
|
||||||
@@ -425,19 +273,14 @@ def change_avatar_confirm_ajax(request):
|
|||||||
print(msg)
|
print(msg)
|
||||||
return JsonResponse({'error': msg}, status=400)
|
return JsonResponse({'error': msg}, status=400)
|
||||||
|
|
||||||
res_Dict = {'url': request.user.user_profile.avatar.url}
|
return JsonResponse({'url': request.user.user_profile.avatar.url})
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def change_profile_confirm_ajax(request):
|
def change_profile_confirm_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
data = request.POST
|
data = request.POST
|
||||||
if not data:
|
if not data:
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -502,20 +345,15 @@ def change_profile_confirm_ajax(request):
|
|||||||
if data_for_save:
|
if data_for_save:
|
||||||
user_profiles.update(**data_for_save)
|
user_profiles.update(**data_for_save)
|
||||||
|
|
||||||
html = get_profile_change_page_content_html(request, data)
|
html = get_profile_change_page_content_html(request)
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = {'html': html}
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def dashboard_ajax(request):
|
def dashboard_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
from .funcs import get_dashboard_page_content_html
|
from .funcs import get_dashboard_page_content_html
|
||||||
@@ -529,32 +367,26 @@ def dashboard_ajax(request):
|
|||||||
return JsonResponse({'html': html}, status=200)
|
return JsonResponse({'html': html}, status=200)
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def change_profile_ajax(request):
|
def change_profile_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
html = get_profile_change_page_content_html(request)
|
html = get_profile_change_page_content_html(request)
|
||||||
return JsonResponse({'html': html}, status=200)
|
return JsonResponse({'html': html}, status=200)
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def my_routes_ajax(request):
|
def my_routes_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
Dict = {
|
Dict = {
|
||||||
}
|
}
|
||||||
|
|
||||||
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
|
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
|
||||||
res_Dict = {'html': html}
|
return JsonResponse({'html': html}, status=200)
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -564,8 +396,6 @@ def login_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = request.POST
|
data = request.POST
|
||||||
@@ -594,16 +424,11 @@ def login_ajax(request):
|
|||||||
html = render_to_string('forms/f_login.html', Dict, request=request)
|
html = render_to_string('forms/f_login.html', Dict, request=request)
|
||||||
return JsonResponse({'html': html}, status=400)
|
return JsonResponse({'html': html}, status=400)
|
||||||
|
|
||||||
if not 'HTTP_REFERER' in request.META or not '/?next=/' in request.META['HTTP_REFERER']:
|
|
||||||
redirect_url = reverse('profile_page', args=['dashboard'])
|
|
||||||
else:
|
|
||||||
redirect_url = request.META['HTTP_REFERER'].split('/?next=')[1]
|
|
||||||
res_Dict = {
|
res_Dict = {
|
||||||
'redirect_url': redirect_url
|
'redirect_url': reverse('profile_page', args=['dashboard'])
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -619,59 +444,45 @@ def login_ajax(request):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send_check_email_after_registration(data_Dict, user):
|
|
||||||
|
def send_registration_mail(data_Dict, user):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
||||||
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
||||||
|
|
||||||
subject = _('Trip With Bonus - Подтверждение регистрации ')
|
subject = _('Добро пожаловать в Trip With Bonus!')
|
||||||
|
|
||||||
Dict = {
|
Dict = {
|
||||||
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
||||||
'project_name': sets['project_name'],
|
'project_name': sets['project_name'],
|
||||||
'domain': sets['domain'],
|
|
||||||
'message_title': subject,
|
'message_title': subject,
|
||||||
}
|
}
|
||||||
Dict.update(data_Dict)
|
Dict.update(data_Dict)
|
||||||
|
|
||||||
html = render_to_string('mail/m_confirm_email.html', Dict)
|
html = render_to_string('mail/m_registration.html', Dict)
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
||||||
mail_sets = get_mail_send_options()
|
mail_sets = get_mail_send_options()
|
||||||
to = [user.email]
|
to = [user.email, 'web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
|
||||||
res = admin_send_mail_by_SMTPlib(
|
res = admin_send_mail_by_SMTPlib(
|
||||||
mail_sets,
|
mail_sets,
|
||||||
subject=subject,
|
subject=subject,
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
from_email=mail_sets['sender_email'], to=to,
|
||||||
html_content=html
|
html_content=html
|
||||||
)
|
)
|
||||||
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
|
|
||||||
admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'send_registration_mail Error = {str(e)}')
|
print(f'send_registration_mail Error = {str(e)}')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def registration_ajax(request):
|
def registration_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = request.POST
|
data = request.POST
|
||||||
@@ -692,34 +503,28 @@ def registration_ajax(request):
|
|||||||
|
|
||||||
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password'])
|
user = User.objects.create_user(username=form.data['email'], email=form.data['email'], password=form.data['password'])
|
||||||
# user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
|
# user = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
|
||||||
# if user:
|
if user:
|
||||||
# auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
||||||
|
|
||||||
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
|
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
|
||||||
user.user_profile.mailing_on = True
|
user.user_profile.mailing_on = True
|
||||||
|
|
||||||
user.last_name = form.data['lastname']
|
user.last_name = form.data['lastname']
|
||||||
user.first_name = form.data['firstname']
|
user.first_name = form.data['firstname']
|
||||||
user.is_active = False
|
|
||||||
user.save()
|
user.save()
|
||||||
user.user_profile.phone = form.data['tel']
|
user.user_profile.phone = form.data['tel']
|
||||||
user.user_profile.authMailCode = uuid1().hex
|
|
||||||
user.user_profile.save()
|
user.user_profile.save()
|
||||||
|
|
||||||
mail_Dict = {
|
mail_Dict = {
|
||||||
'user': user,
|
'user': user,
|
||||||
|
'pass': form.data['password']
|
||||||
}
|
}
|
||||||
|
res = send_registration_mail(mail_Dict, user)
|
||||||
res = send_check_email_after_registration(mail_Dict, user)
|
|
||||||
print(str(res))
|
|
||||||
# res = send_registration_mail(mail_Dict, user)
|
|
||||||
|
|
||||||
res_Dict = {
|
res_Dict = {
|
||||||
# 'redirect_url': reverse('profile_page', args=['dashboard'])
|
'redirect_url': reverse('profile_page', args=['dashboard'])
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from datetime import datetime
|
|||||||
def user_name_str(self):
|
def user_name_str(self):
|
||||||
return f'{self.last_name} {self.first_name}'
|
return f'{self.last_name} {self.first_name}'
|
||||||
|
|
||||||
|
|
||||||
User.add_to_class("__str__", user_name_str)
|
User.add_to_class("__str__", user_name_str)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ from django.contrib.auth import views
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|
||||||
path('registration/', registration_View, name='registration_page'),
|
path('registration/', registration_View, name='registration_page'),
|
||||||
|
|
||||||
path('reset_password/<int:user_id>/<str:token>/',
|
|
||||||
recovery_password_page_View, name='recovery_password_page'),
|
|
||||||
# path('', user_profile_View, name='user_profile'),
|
# path('', user_profile_View, name='user_profile'),
|
||||||
# path('page/chat/<int:user_id>/', chat_w_user_View, name='chat_w_user'),
|
# path('page/chat/<int:user_id>/', chat_w_user_View, name='chat_w_user'),
|
||||||
# path('page/chat/', chat_w_user_View, name='chat_w_user_wo_user_id'),
|
# path('page/chat/', chat_w_user_View, name='chat_w_user_wo_user_id'),
|
||||||
@@ -49,9 +46,9 @@ urlpatterns = [
|
|||||||
#
|
#
|
||||||
# # -----------------------
|
# # -----------------------
|
||||||
#
|
#
|
||||||
path('check_user_registration_and_activate/<int:user_id>/<str:authMailCode>/',
|
# url(r'^check_user_registration_and_activate/(?P<user_id>[\d+]*)/(?P<authCode>[0-9a-z\+\-\_]+)$',
|
||||||
check_user_registration_and_activate,
|
# check_user_registration_and_activate,
|
||||||
name='check_user_registration_and_activate'),
|
# name='check_user_registration_and_activate'),
|
||||||
#
|
#
|
||||||
# # url(r'^user/password/reset/$',
|
# # url(r'^user/password/reset/$',
|
||||||
# # 'django.contrib.auth.views.password_reset',
|
# # 'django.contrib.auth.views.password_reset',
|
||||||
|
|||||||
122
AuthApp/views.py
122
AuthApp/views.py
@@ -5,8 +5,7 @@ from django.shortcuts import render
|
|||||||
from uuid import uuid1
|
from uuid import uuid1
|
||||||
from AuthApp.models import *
|
from AuthApp.models import *
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.urls import reverse
|
from django.http import HttpResponse, Http404
|
||||||
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
|
||||||
from django.template import loader, RequestContext
|
from django.template import loader, RequestContext
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from BaseModels.mailSender import techSendMail
|
from BaseModels.mailSender import techSendMail
|
||||||
@@ -14,68 +13,7 @@ from django.utils.translation import gettext as _
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from .funcs import *
|
from .funcs import *
|
||||||
from GeneralApp.funcs import get_inter_http_response
|
from GeneralApp.funcs import get_inter_http_respose
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
|
|
||||||
|
|
||||||
def send_registration_mail(user):
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
|
||||||
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
|
||||||
|
|
||||||
subject = _('Добро пожаловать в Trip With Bonus!')
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
|
||||||
'project_name': sets['project_name'],
|
|
||||||
'message_title': subject,
|
|
||||||
'user': user
|
|
||||||
}
|
|
||||||
|
|
||||||
html = render_to_string('mail/m_registration.html', Dict)
|
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
|
||||||
mail_sets = get_mail_send_options()
|
|
||||||
to = [user.email]
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
|
|
||||||
admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f'send_registration_mail Error = {str(e)}')
|
|
||||||
return None
|
|
||||||
|
|
||||||
def check_user_registration_and_activate(request, user_id, authMailCode):
|
|
||||||
try:
|
|
||||||
user = User.objects.get(
|
|
||||||
id=user_id,
|
|
||||||
is_active=False,
|
|
||||||
user_profile__authMailCode=authMailCode
|
|
||||||
)
|
|
||||||
user.is_active = True
|
|
||||||
user.save(update_fields=['is_active'])
|
|
||||||
|
|
||||||
res = send_registration_mail(user)
|
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('login_profile'))
|
|
||||||
except User.DoesNotExist:
|
|
||||||
user = None
|
|
||||||
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
|
|
||||||
def registration_View(request):
|
def registration_View(request):
|
||||||
|
|
||||||
@@ -87,7 +25,7 @@ def registration_View(request):
|
|||||||
# if request.p
|
# if request.p
|
||||||
|
|
||||||
t = loader.get_template('pages/profile/p_registration.html')
|
t = loader.get_template('pages/profile/p_registration.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
@@ -103,17 +41,10 @@ def registration_View(request):
|
|||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def profile_page_View(request, page_name, id=None):
|
def profile_page_View(request, page_name, id=None):
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
page_html = get_profile_page_content_html(request, page_name, id)
|
|
||||||
if not page_html:
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
Dict = {
|
Dict = {
|
||||||
'page_html': page_html,
|
'page_html': get_profile_page_content_html(request, page_name, id),
|
||||||
'page_name': page_name,
|
'page_name': page_name,
|
||||||
'page_type': 'profile'
|
'page_type': 'profile'
|
||||||
}
|
}
|
||||||
@@ -123,15 +54,15 @@ def profile_page_View(request, page_name, id=None):
|
|||||||
request.user.user_profile.save(update_fields=['mailing_on'])
|
request.user.user_profile.save(update_fields=['mailing_on'])
|
||||||
del request.session['mailingSubscribeRequired']
|
del request.session['mailingSubscribeRequired']
|
||||||
|
|
||||||
# title = _('Личный кабинет пользователя') + ' ' + request.user.first_name + ' ' + request.user.last_name
|
title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
|
||||||
#
|
|
||||||
# Dict.update({
|
Dict.update({
|
||||||
# 'page': {
|
'page': {
|
||||||
# 'title': title,
|
'title': title,
|
||||||
# 'description': title,
|
'description': title,
|
||||||
# 'keywords': title,
|
'keywords': title,
|
||||||
# }
|
}
|
||||||
# })
|
})
|
||||||
|
|
||||||
# if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
|
# if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
|
||||||
# Dict.update({
|
# Dict.update({
|
||||||
@@ -139,11 +70,11 @@ def profile_page_View(request, page_name, id=None):
|
|||||||
# })
|
# })
|
||||||
|
|
||||||
t = loader.get_template('pages/profile/p_user_profile.html')
|
t = loader.get_template('pages/profile/p_user_profile.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
# @login_required()#login_url='/profile/login/')
|
# @login_required(login_url='/profile/login/')
|
||||||
# def chat_w_user_View(request, user_id=None):
|
# def chat_w_user_View(request, user_id=None):
|
||||||
# from ChatServiceApp.funcs import get_chat_page_content_Dict
|
# from ChatServiceApp.funcs import get_chat_page_content_Dict
|
||||||
#
|
#
|
||||||
@@ -172,7 +103,7 @@ def profile_page_View(request, page_name, id=None):
|
|||||||
# t = loader.get_template('pages/profile/p_user_profile.html')
|
# t = loader.get_template('pages/profile/p_user_profile.html')
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def user_profile_View(request):
|
def user_profile_View(request):
|
||||||
|
|
||||||
Dict = {}
|
Dict = {}
|
||||||
@@ -181,7 +112,7 @@ def user_profile_View(request):
|
|||||||
# request.COOKIES['user_id'] = request.user.id
|
# request.COOKIES['user_id'] = request.user.id
|
||||||
|
|
||||||
t = loader.get_template('pages/profile/p_user_profile.html')
|
t = loader.get_template('pages/profile/p_user_profile.html')
|
||||||
response = get_inter_http_response(t, Dict, request)
|
response = get_inter_http_respose(t, Dict, request)
|
||||||
# response = HttpResponse(t.render(Dict, request))
|
# response = HttpResponse(t.render(Dict, request))
|
||||||
response.set_cookie('user_id', request.user.id)
|
response.set_cookie('user_id', request.user.id)
|
||||||
return response
|
return response
|
||||||
@@ -206,7 +137,7 @@ def login_View(request):
|
|||||||
request.session['mailingSubscribeRequired'] = 'true'
|
request.session['mailingSubscribeRequired'] = 'true'
|
||||||
|
|
||||||
t = loader.get_template('pages/profile/p_login.html')
|
t = loader.get_template('pages/profile/p_login.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
@@ -278,19 +209,12 @@ def decode_get_param(data):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def recovery_password_page_View(request, user_id, token):
|
def recovery_password_user(request, uidb64=None, token=None):
|
||||||
try:
|
from django.contrib.auth.views import PasswordResetConfirmView
|
||||||
user = User.objects.get(id=user_id, user_profile__authMailCode=token)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
Dict = {
|
return PasswordResetConfirmView(request=request, uidb64=uidb64, token=token
|
||||||
'user': user
|
)
|
||||||
}
|
|
||||||
|
|
||||||
t = loader.get_template('pages/profile/p_password_recovery.html')
|
|
||||||
response = get_inter_http_response(t, Dict, request)
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ from django.contrib.contenttypes.fields import GenericRelation
|
|||||||
# add_introspection_rules([], ["^tinymce\.models\.HTMLField"])
|
# add_introspection_rules([], ["^tinymce\.models\.HTMLField"])
|
||||||
|
|
||||||
class BaseModel(models.Model):
|
class BaseModel(models.Model):
|
||||||
name = models.TextField(verbose_name=_("Название"),
|
name = models.TextField(verbose_name=_('Название'),
|
||||||
help_text=_('Название'), null=True, blank=True)
|
help_text=_('Название'), null=True, blank=True)
|
||||||
name_plural = models.TextField(verbose_name=_('Название (множественное число)'),
|
name_plural = models.TextField(verbose_name=_('Название (множественное число)'),
|
||||||
null=True, blank=True)
|
null=True, blank=True)
|
||||||
@@ -29,31 +29,12 @@ class BaseModel(models.Model):
|
|||||||
|
|
||||||
json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True)
|
json_data = models.JSONField(verbose_name=_('Дополнительные данные'), default=dict, blank=True)
|
||||||
|
|
||||||
media_items = GenericRelation('GeneralApp.MediaItem', related_query_name='grel_%(class)s_for_media_item')
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.name:
|
if self.name:
|
||||||
return self.name
|
return self.name
|
||||||
else:
|
else:
|
||||||
return str(self.id)
|
return str(self.id)
|
||||||
|
|
||||||
def get_media_items(self, exclude_kwargs=None):
|
|
||||||
if not exclude_kwargs:
|
|
||||||
exclude_kwargs = {}
|
|
||||||
return self.media_items.exclude(
|
|
||||||
**exclude_kwargs
|
|
||||||
).filter(
|
|
||||||
enable=True
|
|
||||||
).order_by('order')
|
|
||||||
|
|
||||||
def get_video_items(self):
|
|
||||||
exclude_kwargs = {'video': None}
|
|
||||||
return self.get_media_items(exclude_kwargs=exclude_kwargs)
|
|
||||||
|
|
||||||
def get_picture_items(self):
|
|
||||||
exclude_kwargs = {'picture': None}
|
|
||||||
return self.get_media_items(exclude_kwargs=exclude_kwargs)
|
|
||||||
|
|
||||||
def pop_node_by_name(self, node_name):
|
def pop_node_by_name(self, node_name):
|
||||||
if not self.json_data or not node_name in self.json_data:
|
if not self.json_data or not node_name in self.json_data:
|
||||||
return None
|
return None
|
||||||
@@ -127,6 +108,7 @@ class BaseModelViewPage(BaseModel):
|
|||||||
FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True)
|
FAQ_title = models.CharField(max_length=250, verbose_name=_(u'FAQ Заголовок'), null=True, blank=True)
|
||||||
FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
|
FAQ_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|||||||
@@ -1,113 +0,0 @@
|
|||||||
import json
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from requests_pkcs12 import get,post
|
|
||||||
|
|
||||||
# для песочницы
|
|
||||||
# pkcs12_filename = 'dvldigitalprojects.p12'
|
|
||||||
# pkcs12_password = 'QNlhRStcY7mB'
|
|
||||||
# api_pass = 'aPqSRVZhxFjjSqbB'
|
|
||||||
|
|
||||||
# для прода
|
|
||||||
# pkcs12_filename = 'dvldigitalprojects.p12'
|
|
||||||
# pkcs12_password = 'fzSBm6WISje7'
|
|
||||||
# api_pass = 't9g2+bZSvxNxCu+t'
|
|
||||||
|
|
||||||
|
|
||||||
def get_domain_url():
|
|
||||||
return settings.PAY_SYSTEM_URL #'https://sandboxapi.paymtech.kz/'
|
|
||||||
|
|
||||||
def get_kwargs_for_request():
|
|
||||||
return {
|
|
||||||
'headers': {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
},
|
|
||||||
'auth': ('dvldigitalprojects', settings.API_PASS),
|
|
||||||
'pkcs12_filename': settings.PKCS12_FILENAME,
|
|
||||||
'pkcs12_password': settings.PKCS12_PASS
|
|
||||||
}
|
|
||||||
|
|
||||||
def ping():
|
|
||||||
|
|
||||||
url = f'{get_domain_url()}ping'
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
msg = f'GET {url}'
|
|
||||||
print(msg)
|
|
||||||
res = get(
|
|
||||||
url,
|
|
||||||
**get_kwargs_for_request()
|
|
||||||
)
|
|
||||||
|
|
||||||
msg = f'answer received = {str(res)}'
|
|
||||||
print(msg)
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'Exception GET {url} = {str(e)} ({str(res)})'
|
|
||||||
print(msg)
|
|
||||||
res = None
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def get_order_status(bank_order_id):
|
|
||||||
|
|
||||||
url = f'{get_domain_url()}orders/{str(bank_order_id)}'
|
|
||||||
|
|
||||||
res = None
|
|
||||||
|
|
||||||
data = {
|
|
||||||
'expand': [
|
|
||||||
'card', 'client', 'location', 'custom_fields',
|
|
||||||
'issuer', 'secure3d', 'operations', 'cashflow'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
msg = f'GET {url}'
|
|
||||||
print(msg)
|
|
||||||
res = get(
|
|
||||||
url,
|
|
||||||
data=json.dumps(data),
|
|
||||||
**get_kwargs_for_request()
|
|
||||||
)
|
|
||||||
|
|
||||||
msg = f'get_order_status answer received = {str(res)}'
|
|
||||||
print(msg)
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'Exception get_order_status GET {url} = {str(e)} ({str(res)})'
|
|
||||||
print(msg)
|
|
||||||
res = None
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def create_order(data):
|
|
||||||
|
|
||||||
url = f'{get_domain_url()}orders/create'
|
|
||||||
|
|
||||||
res = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
msg = f'POST {url}'
|
|
||||||
print(msg)
|
|
||||||
res = post(
|
|
||||||
url,
|
|
||||||
data=json.dumps(data),
|
|
||||||
**get_kwargs_for_request()
|
|
||||||
)
|
|
||||||
|
|
||||||
msg = f'create_order answer received = {str(res.text)}'
|
|
||||||
# if res:# and res.status_code > 300:
|
|
||||||
# msg += f' > ({str(res.text)})'
|
|
||||||
print(msg)
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'Exception create_order POST {url} = {str(e)} ({str(res)})'
|
|
||||||
if res:
|
|
||||||
msg += f' > ({str(res.text)})'
|
|
||||||
print(msg)
|
|
||||||
res = None
|
|
||||||
|
|
||||||
return res
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
from sets.admin import *
|
|
||||||
from .models import *
|
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
class Admin_SubscribeOrder(Admin_BaseModel):
|
|
||||||
|
|
||||||
fieldsets = (
|
|
||||||
(None, {
|
|
||||||
'classes': ['wide'],
|
|
||||||
'fields': (
|
|
||||||
('user', 'subscribe', 'subscribe_for_user'),
|
|
||||||
('enable', 'order'),
|
|
||||||
('sum', 'currency'),
|
|
||||||
('status', 'last_operation_status'),
|
|
||||||
('bank_order_id', 'pay_page'),
|
|
||||||
'json_data',
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
list_display = [
|
|
||||||
'id', 'enable',
|
|
||||||
'user', 'subscribe', 'subscribe_for_user',
|
|
||||||
'bank_order_id',
|
|
||||||
'sum', 'currency',
|
|
||||||
'status', 'last_operation_status',
|
|
||||||
'order', 'modifiedDT', 'createDT'
|
|
||||||
]
|
|
||||||
|
|
||||||
list_display_links = ['id', 'user', 'subscribe']
|
|
||||||
list_editable = ['enable']
|
|
||||||
|
|
||||||
readonly_fields = ['subscribe_for_user', 'sum', 'currency', 'modifiedDT', 'createDT']
|
|
||||||
|
|
||||||
list_filter = ['enable', 'status', 'modifiedDT', 'createDT']
|
|
||||||
search_fields = ['id', 'last_operation_status', 'status']
|
|
||||||
# filter_horizontal = ['options']
|
|
||||||
|
|
||||||
admin.site.register(SubscribeOrder, Admin_SubscribeOrder)
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class BillingappConfig(AppConfig):
|
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
|
||||||
name = 'BillingApp'
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
from .models import *
|
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
def get_order_status(order):
|
|
||||||
from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import get_order_status
|
|
||||||
res_status = None
|
|
||||||
|
|
||||||
if not order or not order.bank_order_id:
|
|
||||||
return order
|
|
||||||
|
|
||||||
try:
|
|
||||||
res_data = get_order_status(order.bank_order_id)
|
|
||||||
|
|
||||||
res = json.loads(res_data.text)
|
|
||||||
res = res['orders'][0]
|
|
||||||
order.json_data['status'] = res
|
|
||||||
|
|
||||||
order.status = res['status']
|
|
||||||
|
|
||||||
|
|
||||||
# if res['amount'] == res['amount_charged'] and res['status'] == 'charged':
|
|
||||||
order.save()
|
|
||||||
# return order.status
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'Exception get_order_status = {str(e)}'
|
|
||||||
if order:
|
|
||||||
msg = f'Exception get_order_status (data = {str(order.id)}) = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
return order
|
|
||||||
|
|
||||||
def get_orders_for_user(user):
|
|
||||||
|
|
||||||
orders = SubscribeOrder.objects.filter(
|
|
||||||
enable=True,
|
|
||||||
user=user,
|
|
||||||
subscribe_for_user=None,
|
|
||||||
createDT__gt=datetime.now() - timedelta(hours=1)
|
|
||||||
).order_by('subscribe', '-createDT').distinct('subscribe')
|
|
||||||
|
|
||||||
SubscribeOrder.objects.filter(
|
|
||||||
user=user
|
|
||||||
).exclude(
|
|
||||||
id__in=orders.values_list('id', flat=True)
|
|
||||||
).update(enable=False)
|
|
||||||
|
|
||||||
return orders
|
|
||||||
|
|
||||||
|
|
||||||
def create_subscribe_order(data):
|
|
||||||
order = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
order = SubscribeOrder.objects.create(**data)
|
|
||||||
|
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
|
||||||
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
|
||||||
|
|
||||||
from BaseModels.pay_systems.DVL_Group_kaz.api.funcs import create_order
|
|
||||||
data = {
|
|
||||||
'currency': data['currency'],
|
|
||||||
'amount': data['sum'],
|
|
||||||
'description': f'Заказ {order.id} на подписку '
|
|
||||||
f'{data["subscribe"].name} '
|
|
||||||
f'для пользователя {data["user"].username}',
|
|
||||||
'options': {
|
|
||||||
'force3d': 1,
|
|
||||||
'auto_charge': 1,
|
|
||||||
'return_url': f'{sets["domain"]}/profile/page/my_subscribe/'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res_data = create_order(data)
|
|
||||||
|
|
||||||
order.pay_page = res_data.headers.get('location')
|
|
||||||
|
|
||||||
res = json.loads(res_data.text)
|
|
||||||
res = res['orders'][0]
|
|
||||||
order.json_data['create_order'] = res
|
|
||||||
|
|
||||||
order.modifiedDT = datetime.strptime(res['updated'], '%Y-%m-%d %H:%M:%S')
|
|
||||||
order.status = res['status']
|
|
||||||
order.bank_order_id = res['id']
|
|
||||||
if 'segment' in res:
|
|
||||||
order.segment = res['segment']
|
|
||||||
if 'merchant_order_id' in res:
|
|
||||||
order.merchant_order_id = res['merchant_order_id']
|
|
||||||
order.save()
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'Exception create_subscribe_order (data = {str(data)}) = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
return order
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-04-19 16:24
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('SubscribesApp', '0003_alter_subscribe_bg_color_alter_subscribe_text_color'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='SubscribeOrder',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
|
|
||||||
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
|
|
||||||
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
|
|
||||||
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
|
|
||||||
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
|
|
||||||
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
|
|
||||||
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
|
|
||||||
('sum', models.PositiveSmallIntegerField(verbose_name='Сумма')),
|
|
||||||
('currency', models.CharField(max_length=3, verbose_name='Валюта')),
|
|
||||||
('segment', models.CharField(verbose_name='ID Сегмента')),
|
|
||||||
('merchant_order_id', models.CharField(verbose_name='merchant_order_id')),
|
|
||||||
('bank_order_id', models.CharField(verbose_name='ID заказа в банке')),
|
|
||||||
('status', models.CharField(verbose_name='Статус заказа в банке')),
|
|
||||||
('subscribe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_subscribe', to='SubscribesApp.subscribe', verbose_name='Подписка')),
|
|
||||||
('subscribe_for_user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user_subscribe', to='SubscribesApp.subscribeforuser', verbose_name='Подписка пользователя')),
|
|
||||||
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user', to='SubscribesApp.subscribe', verbose_name='Пользователь')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'Заказ на подписку',
|
|
||||||
'verbose_name_plural': 'Заказы на подписки',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-04-19 16:29
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
('BillingApp', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='user',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subscribe_orders_for_user', to=settings.AUTH_USER_MODEL, verbose_name='Пользователь'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-04-19 16:36
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BillingApp', '0002_alter_subscribeorder_user'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='pay_page',
|
|
||||||
field=models.URLField(blank=True, default=None, null=True, verbose_name='Ссылка на страницу оплаты'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='bank_order_id',
|
|
||||||
field=models.CharField(default='', verbose_name='ID заказа в банке'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='merchant_order_id',
|
|
||||||
field=models.CharField(default='', verbose_name='merchant_order_id'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='segment',
|
|
||||||
field=models.CharField(default='', verbose_name='ID Сегмента'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='status',
|
|
||||||
field=models.CharField(default='', verbose_name='Статус заказа в банке'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='sum',
|
|
||||||
field=models.PositiveSmallIntegerField(default=0, verbose_name='Сумма'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-04-19 16:47
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BillingApp', '0003_subscribeorder_pay_page_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='bank_order_id',
|
|
||||||
field=models.CharField(default=None, null=True, verbose_name='ID заказа в банке'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='currency',
|
|
||||||
field=models.CharField(default='USD', max_length=3, verbose_name='Валюта'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='merchant_order_id',
|
|
||||||
field=models.CharField(default=None, null=True, verbose_name='merchant_order_id'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='segment',
|
|
||||||
field=models.CharField(default=None, null=True, verbose_name='ID Сегмента'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='status',
|
|
||||||
field=models.CharField(default=None, null=True, verbose_name='Статус заказа в банке'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-04-19 17:57
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BillingApp', '0004_alter_subscribeorder_bank_order_id_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='last_operation_status',
|
|
||||||
field=models.CharField(default=None, null=True, verbose_name='Статус последней операции'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-07-12 17:23
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('BillingApp', '0005_subscribeorder_last_operation_status'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='subscribeorder',
|
|
||||||
name='currency',
|
|
||||||
field=models.CharField(default='KZT', max_length=3, verbose_name='Валюта'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
from BaseModels.base_models import BaseModel
|
|
||||||
from SubscribesApp.models import Subscribe, SubscribeForUser
|
|
||||||
from AuthApp.models import User
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
class SubscribeOrder(BaseModel):
|
|
||||||
|
|
||||||
subscribe = models.ForeignKey(
|
|
||||||
Subscribe, verbose_name=_('Подписка'),
|
|
||||||
on_delete=models.SET_NULL, blank=True, null=True,
|
|
||||||
related_name='subscribe_orders_for_subscribe'
|
|
||||||
)
|
|
||||||
|
|
||||||
user = models.ForeignKey(
|
|
||||||
User, verbose_name=_('Пользователь'),
|
|
||||||
on_delete=models.SET_NULL, blank=True, null=True,
|
|
||||||
related_name='subscribe_orders_for_user'
|
|
||||||
)
|
|
||||||
|
|
||||||
subscribe_for_user = models.OneToOneField(
|
|
||||||
SubscribeForUser, verbose_name=_('Подписка пользователя'),
|
|
||||||
on_delete=models.SET_NULL, blank=True, null=True,
|
|
||||||
related_name='subscribe_orders_for_user_subscribe'
|
|
||||||
)
|
|
||||||
|
|
||||||
sum = models.PositiveSmallIntegerField(verbose_name=_('Сумма'), default=0)
|
|
||||||
currency = models.CharField(verbose_name=_('Валюта'), max_length=3, default='KZT')
|
|
||||||
segment = models.CharField(verbose_name=_('ID Сегмента'), null=True, default=None)
|
|
||||||
merchant_order_id = models.CharField(verbose_name=_('merchant_order_id'), null=True, default=None)
|
|
||||||
bank_order_id = models.CharField(verbose_name=_('ID заказа в банке'), null=True, default=None)
|
|
||||||
|
|
||||||
status = models.CharField(verbose_name=_('Статус заказа в банке'), null=True, default=None)
|
|
||||||
last_operation_status = models.CharField(verbose_name=_('Статус последней операции'), null=True, default=None)
|
|
||||||
|
|
||||||
pay_page = models.URLField(verbose_name=_('Ссылка на страницу оплаты'), null=True, blank=True, default=None)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('Заказ на подписку')
|
|
||||||
verbose_name_plural = _('Заказы на подписки')
|
|
||||||
|
|
||||||
def activate_subscribe_for_user(self):
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
'user': self.user,
|
|
||||||
'subscribe': self.subscribe,
|
|
||||||
'last_paid_DT': datetime.now(),
|
|
||||||
'receive_finish_subscribe_msg': True,
|
|
||||||
# 'enable': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
from SubscribesApp.funcs import create_subscribe_by_data
|
|
||||||
subscribe_for_user = create_subscribe_by_data(kwargs)
|
|
||||||
self.subscribe_for_user = subscribe_for_user
|
|
||||||
self.enable = False
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
subscribe_for_user.activate(
|
|
||||||
paid_period_from_DT=datetime.now(),
|
|
||||||
paid_period_to_DT=datetime.now() + timedelta(hours=self.subscribe.period)
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
res = 'Заказ'
|
|
||||||
if self.subscribe:
|
|
||||||
res += f' на подписку {self.subscribe.name}'
|
|
||||||
if self.user:
|
|
||||||
res += f' для {self.user.username}'
|
|
||||||
|
|
||||||
if not res:
|
|
||||||
res += f' {str(self.id)}'
|
|
||||||
return res
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
# Create your tests here.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
@@ -17,9 +17,6 @@ from AuthApp.funcs import get_user_timezone_Dict
|
|||||||
|
|
||||||
|
|
||||||
def get_unanswered_msgs_count_for_user(user):
|
def get_unanswered_msgs_count_for_user(user):
|
||||||
if not user or not user.is_authenticated:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
|
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
|
||||||
return msgs.count()
|
return msgs.count()
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,12 @@ from channels.layers import get_channel_layer
|
|||||||
from asgiref.sync import async_to_sync
|
from asgiref.sync import async_to_sync
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def get_file_from_msg_ajax(request):
|
def get_file_from_msg_ajax(request):
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -38,9 +35,7 @@ def get_file_from_msg_ajax(request):
|
|||||||
res_Dict = file
|
res_Dict = file
|
||||||
break
|
break
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse(res_Dict, status=200)
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'get_file_from_msg_ajax Error = {str(e)}'
|
msg = f'get_file_from_msg_ajax Error = {str(e)}'
|
||||||
@@ -48,15 +43,12 @@ def get_file_from_msg_ajax(request):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def show_chat_w_user_ajax(request):
|
def show_chat_w_user_ajax(request):
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -65,12 +57,10 @@ def show_chat_w_user_ajax(request):
|
|||||||
|
|
||||||
tpl_name = 'blocks/profile/b_chats.html'
|
tpl_name = 'blocks/profile/b_chats.html'
|
||||||
|
|
||||||
html = render_to_string(tpl_name, Dict, request=request)
|
|
||||||
|
|
||||||
res_Dict = {'html': html}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
html = render_to_string(tpl_name, Dict, request=request)
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
return JsonResponse({'html': html}, status=200)
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'show_chat_w_user_ajax Error = {str(e)}'
|
msg = f'show_chat_w_user_ajax Error = {str(e)}'
|
||||||
@@ -84,9 +74,6 @@ def update_chat_ajax2(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
res_Dict = {}
|
res_Dict = {}
|
||||||
msgs = []
|
msgs = []
|
||||||
Dict = {}
|
Dict = {}
|
||||||
@@ -161,9 +148,7 @@ def update_chat_ajax2(request):
|
|||||||
res_Dict.update({
|
res_Dict.update({
|
||||||
'required_beep': required_beep,
|
'required_beep': required_beep,
|
||||||
})
|
})
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
return JsonResponse(res_Dict, status=200)
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'update_chat_ajax2 Error = {str(e)}'
|
msg = f'update_chat_ajax2 Error = {str(e)}'
|
||||||
@@ -178,9 +163,6 @@ def update_chat_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
res_Dict = {}
|
res_Dict = {}
|
||||||
msgs = []
|
msgs = []
|
||||||
Dict = {}
|
Dict = {}
|
||||||
@@ -274,17 +256,14 @@ def update_chat_ajax(request):
|
|||||||
res_Dict.update({
|
res_Dict.update({
|
||||||
'required_beep': required_beep,
|
'required_beep': required_beep,
|
||||||
})
|
})
|
||||||
|
return JsonResponse(res_Dict, status=200)
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'update_chat_ajax Error = {str(e)}'
|
msg = f'update_chat_ajax Error = {str(e)}'
|
||||||
return JsonResponse({'error': msg}, status=400)
|
return JsonResponse({'error': msg}, status=400)
|
||||||
|
|
||||||
|
|
||||||
# @login_required()#login_url='/profile/login/')
|
# @login_required(login_url='/profile/login/')
|
||||||
# def send_msg_ajax(request):
|
# def send_msg_ajax(request):
|
||||||
# from AuthApp.models import User
|
# from AuthApp.models import User
|
||||||
#
|
#
|
||||||
@@ -396,15 +375,12 @@ def update_chat_ajax(request):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def support_show_chat_by_ticket_ajax(request):
|
def support_show_chat_by_ticket_ajax(request):
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -444,26 +420,20 @@ def support_show_chat_by_ticket_ajax(request):
|
|||||||
tpl_name = 'blocks/profile/b_support_chat.html'
|
tpl_name = 'blocks/profile/b_support_chat.html'
|
||||||
Dict.update(get_user_timezone_Dict(request.user, request=request))
|
Dict.update(get_user_timezone_Dict(request.user, request=request))
|
||||||
html = render_to_string(tpl_name, Dict, request=request)
|
html = render_to_string(tpl_name, Dict, request=request)
|
||||||
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = {'html': html}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'support_show_chat_by_ticket_ajax Error = {str(e)}'
|
msg = f'support_show_chat_by_ticket_ajax Error = {str(e)}'
|
||||||
return JsonResponse({'error': msg}, status=400)
|
return JsonResponse({'error': msg}, status=400)
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def support_create_ticket_form_ajax(request):
|
def support_create_ticket_form_ajax(request):
|
||||||
from ChatServiceApp.forms import TicketForm
|
from ChatServiceApp.forms import TicketForm
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
Dict = {
|
Dict = {
|
||||||
'form': TicketForm()
|
'form': TicketForm()
|
||||||
@@ -474,23 +444,16 @@ def support_create_ticket_form_ajax(request):
|
|||||||
tpl_name = 'blocks/profile/b_create_ticket.html'
|
tpl_name = 'blocks/profile/b_create_ticket.html'
|
||||||
|
|
||||||
html = render_to_string(tpl_name, Dict, request=request)
|
html = render_to_string(tpl_name, Dict, request=request)
|
||||||
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = {'html': html}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def create_ticket_ajax(request):
|
def create_ticket_ajax(request):
|
||||||
from ChatServiceApp.forms import TicketForm
|
from ChatServiceApp.forms import TicketForm
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = request.POST
|
data = request.POST
|
||||||
@@ -549,8 +512,6 @@ def create_ticket_ajax(request):
|
|||||||
'html': html
|
'html': html
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ from .models import *
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
||||||
|
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
@@ -49,7 +47,7 @@ class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
|||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not obj or obj.url in ('main', 'works'):
|
if obj.url in ('main', 'spec_technics', 'works'):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
admin.site.register(StaticPage,Admin_StaticPage)
|
admin.site.register(StaticPage,Admin_StaticPage)
|
||||||
|
|||||||
@@ -1,47 +1,6 @@
|
|||||||
from django.http import HttpResponse, Http404, FileResponse
|
from django.http import HttpResponse, Http404, FileResponse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
def get_and_set_lang(request):
|
|
||||||
from django.utils.translation import activate, get_language
|
|
||||||
lang = None
|
|
||||||
|
|
||||||
cur_url_list = request.path.split('/')
|
|
||||||
if len(cur_url_list) > 1 and cur_url_list[1] in settings.MODELTRANSLATION_LANGUAGES:
|
|
||||||
lang = cur_url_list[1]
|
|
||||||
|
|
||||||
if not lang:
|
|
||||||
referer_url = request.META.get('HTTP_REFERER')
|
|
||||||
if referer_url:
|
|
||||||
url_list = referer_url.split('//')
|
|
||||||
if len(url_list) > 1:
|
|
||||||
url_list = url_list[1].split('/')
|
|
||||||
if len(url_list) > 1 and url_list[1] in settings.MODELTRANSLATION_LANGUAGES:
|
|
||||||
lang = url_list[1]
|
|
||||||
|
|
||||||
if not lang:
|
|
||||||
lang = get_language()
|
|
||||||
|
|
||||||
if not lang:
|
|
||||||
lang = 'en'
|
|
||||||
|
|
||||||
activate(lang)
|
|
||||||
|
|
||||||
return lang
|
|
||||||
|
|
||||||
|
|
||||||
def get_add_to_ajax_response_Dict(user):
|
|
||||||
context_Dict = {}
|
|
||||||
|
|
||||||
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
|
|
||||||
context_Dict.update({
|
|
||||||
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(user)
|
|
||||||
})
|
|
||||||
|
|
||||||
return context_Dict
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_inter_Dict(user):
|
def get_inter_Dict(user):
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
from SubscribesApp.funcs import get_cur_user_subscribe
|
||||||
@@ -62,7 +21,7 @@ def get_inter_Dict(user):
|
|||||||
|
|
||||||
return Dict
|
return Dict
|
||||||
|
|
||||||
def get_inter_http_response(template_obj, context_Dict, request):
|
def get_inter_http_respose(template_obj, context_Dict, request):
|
||||||
|
|
||||||
context_Dict.update(get_inter_Dict(request.user))
|
context_Dict.update(get_inter_Dict(request.user))
|
||||||
|
|
||||||
@@ -83,9 +42,4 @@ def get_inter_http_response(template_obj, context_Dict, request):
|
|||||||
# if text and title and not request.user.is_anonymous:
|
# if text and title and not request.user.is_anonymous:
|
||||||
# send_push(user=request.user, title=title, text=text)
|
# send_push(user=request.user, title=title, text=text)
|
||||||
|
|
||||||
from ChatServiceApp.funcs import get_unanswered_msgs_count_for_user
|
|
||||||
context_Dict.update({
|
|
||||||
'unanswered_msgs_count': get_unanswered_msgs_count_for_user(request.user)
|
|
||||||
})
|
|
||||||
|
|
||||||
return HttpResponse(template_obj.render(context_Dict, request))
|
return HttpResponse(template_obj.render(context_Dict, request))
|
||||||
@@ -13,15 +13,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
|
|||||||
res = {}
|
res = {}
|
||||||
opts = opts.values('opt_type', 'value', 'prefix')
|
opts = opts.values('opt_type', 'value', 'prefix')
|
||||||
for item in opts:
|
for item in opts:
|
||||||
# if item['opt_type'] == 'domain':
|
if item['opt_type'] == 'domain':
|
||||||
#
|
|
||||||
# try:
|
try:
|
||||||
# from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
# current_site = Site.objects.get_current()
|
current_site = Site.objects.get_current()
|
||||||
# res.update({item['opt_type']: current_site.domain})
|
res.update({item['opt_type']: current_site.domain})
|
||||||
# # continue
|
continue
|
||||||
# except Exception as e:
|
except Exception as e:
|
||||||
# print(str(e))
|
print(str(e))
|
||||||
|
|
||||||
if item['prefix']:
|
if item['prefix']:
|
||||||
res.update({item['opt_type']: f"{item['prefix']}{item['value']}"})
|
res.update({item['opt_type']: f"{item['prefix']}{item['value']}"})
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
from django.core.management.base import BaseCommand
|
|
||||||
from datetime import datetime
|
|
||||||
from BaseModels.mailSender import techSendMail
|
|
||||||
from ...funcs_options import get_options_by_opt_types, get_mail_send_options
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
|
||||||
mail_sets = get_mail_send_options()
|
|
||||||
|
|
||||||
log = ''
|
|
||||||
log_begin_DT = datetime.now()
|
|
||||||
msg = str(log_begin_DT)
|
|
||||||
print('-------------')
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
try:
|
|
||||||
from RoutesApp.search_matches import search_matches
|
|
||||||
msg = search_matches()
|
|
||||||
if msg:
|
|
||||||
print(msg)
|
|
||||||
log += f'\n{msg}'
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'every_1hour_start search_matches fail = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
techSendMail(mail_sets, msg, title='every_1hour_start search_matches')
|
|
||||||
|
|
||||||
|
|
||||||
if datetime.now().hour == 19:
|
|
||||||
try:
|
|
||||||
from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
|
|
||||||
msg = send_mail_for_user_subscribes_that_is_going_to_finish()
|
|
||||||
if msg:
|
|
||||||
print(msg)
|
|
||||||
log += f'\n{msg}'
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'send_mail_for_user_subscribes_that_is_going_to_finish search_matches fail = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
techSendMail(mail_sets, msg, title='every_1hour_start send_mail_for_user_subscribes_that_is_going_to_finish')
|
|
||||||
|
|
||||||
if log:
|
|
||||||
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-11-15 14:50
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
|
||||||
('GeneralApp', '0005_option_name_en_option_name_ru_option_prefix_en_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='MediaItem',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('name', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
|
|
||||||
('name_ru', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
|
|
||||||
('name_en', models.TextField(blank=True, help_text='Название', null=True, verbose_name='Название')),
|
|
||||||
('name_plural', models.TextField(blank=True, null=True, verbose_name='Название (множественное число)')),
|
|
||||||
('order', models.IntegerField(blank=True, null=True, verbose_name='Очередность отображения')),
|
|
||||||
('createDT', models.DateTimeField(auto_now_add=True, verbose_name='Дата и время создания')),
|
|
||||||
('modifiedDT', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего изменения')),
|
|
||||||
('enable', models.BooleanField(db_index=True, default=True, verbose_name='Включено')),
|
|
||||||
('json_data', models.JSONField(blank=True, default=dict, verbose_name='Дополнительные данные')),
|
|
||||||
('object_id', models.PositiveIntegerField()),
|
|
||||||
('picture', models.ImageField(blank=True, null=True, upload_to='media/', verbose_name='Фото')),
|
|
||||||
('video', models.FileField(blank=True, null=True, upload_to='media/video/', verbose_name='Видео')),
|
|
||||||
('comment', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
|
|
||||||
('comment_ru', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
|
|
||||||
('comment_en', models.TextField(blank=True, null=True, verbose_name='Комментарий')),
|
|
||||||
('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'verbose_name': 'Медиа элемент',
|
|
||||||
'verbose_name_plural': 'Медиа элементы',
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-11-15 15:58
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('GeneralApp', '0006_mediaitem'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='mediaitem',
|
|
||||||
name='picture',
|
|
||||||
field=models.ImageField(blank=True, null=True, upload_to='uploads/', verbose_name='Фото'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='mediaitem',
|
|
||||||
name='video',
|
|
||||||
field=models.FileField(blank=True, null=True, upload_to='uploads/video/', verbose_name='Видео'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-11-15 15:59
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('GeneralApp', '0007_alter_mediaitem_picture_alter_mediaitem_video'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='mediaitem',
|
|
||||||
name='picture',
|
|
||||||
field=models.ImageField(blank=True, null=True, upload_to='media_items/photo/', verbose_name='Фото'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='mediaitem',
|
|
||||||
name='video',
|
|
||||||
field=models.FileField(blank=True, null=True, upload_to='media_items/video/', verbose_name='Видео'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -3,26 +3,6 @@ from BaseModels.base_models import BaseModelViewPage, BaseModel
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
# from ckeditor.fields import RichTextField
|
# from ckeditor.fields import RichTextField
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from ckeditor_uploader.fields import RichTextUploadingField
|
||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
||||||
|
|
||||||
|
|
||||||
class MediaItem(BaseModel):
|
|
||||||
|
|
||||||
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
|
|
||||||
object_id = models.PositiveIntegerField()
|
|
||||||
content_object = GenericForeignKey('content_type', 'object_id')
|
|
||||||
|
|
||||||
picture = models.ImageField(upload_to='media_items/photo/', verbose_name=_('Фото'), null=True, blank=True)
|
|
||||||
video = models.FileField(upload_to='media_items/video/', verbose_name=_('Видео'), null=True, blank=True)
|
|
||||||
|
|
||||||
comment = models.TextField(verbose_name=_('Комментарий'), null=True, blank=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = _('Медиа элемент')
|
|
||||||
verbose_name_plural = _('Медиа элементы')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class StaticPage(BaseModelViewPage):
|
class StaticPage(BaseModelViewPage):
|
||||||
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
|
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
|
||||||
@@ -49,6 +29,9 @@ class Option(BaseModel):
|
|||||||
|
|
||||||
class FAQitem(BaseModel):
|
class FAQitem(BaseModel):
|
||||||
|
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
|
||||||
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
|
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)
|
||||||
object_id = models.PositiveIntegerField()
|
object_id = models.PositiveIntegerField()
|
||||||
content_object = GenericForeignKey('content_type', 'object_id')
|
content_object = GenericForeignKey('content_type', 'object_id')
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def del_amp_symbols(value):
|
|||||||
@stringfilter
|
@stringfilter
|
||||||
def del_lang_from_path(value):
|
def del_lang_from_path(value):
|
||||||
path_list = value.split('/')
|
path_list = value.split('/')
|
||||||
path = '/' + '/'.join(path_list[4:])
|
path = '/' + '/'.join(path_list[2:])
|
||||||
|
|
||||||
# for i in path_list[1:]:
|
# for i in path_list[1:]:
|
||||||
# path.join(i + '/')
|
# path.join(i + '/')
|
||||||
|
|||||||
@@ -27,9 +27,3 @@ class FAQitem_TranslationOptions(TranslationOptions):
|
|||||||
)
|
)
|
||||||
translator.register(FAQitem, FAQitem_TranslationOptions)
|
translator.register(FAQitem, FAQitem_TranslationOptions)
|
||||||
|
|
||||||
class MediaItem_TranslationOptions(TranslationOptions):
|
|
||||||
fields = (
|
|
||||||
'name', 'comment',
|
|
||||||
)
|
|
||||||
translator.register(MediaItem, MediaItem_TranslationOptions)
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ from .views import *
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', MainPage, name='main'),
|
path('', MainPage, name='main'),
|
||||||
path('mover_landing_page/', LandingMoverPage, name='mover_landing_page'),
|
|
||||||
path('customer_landing_page/', LandingCustomerPage, name='customer_landing_page'),
|
|
||||||
|
|
||||||
|
|
||||||
path('page/<str:url>/', StaticPageView, name='static_page'),
|
path('page/<str:url>/', StaticPageView, name='static_page'),
|
||||||
path('test_code', test_code, name='test_code'),
|
path('test_code', test_code, name='test_code'),
|
||||||
path('generate_routes/<int:routes_count>/', generate_routes, name='generate_routes'),
|
|
||||||
]
|
]
|
||||||
@@ -3,10 +3,9 @@ import json
|
|||||||
from django.http import HttpResponse, Http404, FileResponse
|
from django.http import HttpResponse, Http404, FileResponse
|
||||||
from django.template import loader, RequestContext
|
from django.template import loader, RequestContext
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
|
||||||
from .models import *
|
from .models import *
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from .funcs import get_inter_http_response
|
from .funcs import get_inter_http_respose
|
||||||
from django.http.response import JsonResponse, HttpResponse
|
from django.http.response import JsonResponse, HttpResponse
|
||||||
from django.views.decorators.http import require_GET, require_POST
|
from django.views.decorators.http import require_GET, require_POST
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
@@ -14,124 +13,49 @@ from django.contrib.auth.models import User
|
|||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from webpush import send_user_notification
|
from webpush import send_user_notification
|
||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
def generate_routes(request, routes_count):
|
|
||||||
if (not request.user
|
|
||||||
or not request.user.is_active
|
|
||||||
or not request.user.is_authenticated
|
|
||||||
or not request.user.is_staff
|
|
||||||
):
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
|
def test_code(request):
|
||||||
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
|
from RoutesApp.funcs import get_city_by_type_transport_and_address_point
|
||||||
from RoutesApp.models import Route
|
from RoutesApp.models import Route
|
||||||
from ReferenceDataApp.models import Airport, City
|
from ReferenceDataApp.models import Airport, City
|
||||||
|
|
||||||
res = None
|
# import allauth
|
||||||
|
# from allauth.socialaccount.models import SocialApp
|
||||||
from_air = Airport.objects.get(iata_code='MSQ')
|
# apps = SocialApp.objects.all()
|
||||||
to_air = Airport.objects.get(iata_code='SVO')
|
# apps.delete()
|
||||||
|
|
||||||
routes = [
|
|
||||||
Route(
|
|
||||||
type_transport='road',
|
|
||||||
departure_DT=datetime.now() + timedelta(days=7),
|
|
||||||
arrival_DT=datetime.now() + timedelta(days=8),
|
|
||||||
from_address_point=to_air.city.id,
|
|
||||||
to_address_point=from_air.city.id,
|
|
||||||
from_city=to_air.city,
|
|
||||||
to_city=from_air.city,
|
|
||||||
weight=item,
|
|
||||||
phone='0987654321',
|
|
||||||
owner=request.user
|
|
||||||
) for item in range(routes_count)
|
|
||||||
]
|
|
||||||
|
|
||||||
Route.objects.bulk_create(routes)
|
|
||||||
|
|
||||||
if res:
|
|
||||||
if type(res) == str:
|
|
||||||
return HttpResponse(res)
|
|
||||||
else:
|
|
||||||
return res
|
|
||||||
|
|
||||||
return HttpResponse('finished')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_code(request):
|
|
||||||
|
|
||||||
if (not request.user
|
|
||||||
or not request.user.is_active
|
|
||||||
or not request.user.is_authenticated
|
|
||||||
or not request.user.is_staff
|
|
||||||
):
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
res = ''
|
|
||||||
|
|
||||||
from RoutesApp.search_matches import search_matches
|
from RoutesApp.search_matches import search_matches
|
||||||
from RoutesApp.models import Route
|
search_matches()
|
||||||
search_matches(Route.objects.filter(id=16))
|
|
||||||
|
|
||||||
# from RoutesApp.funcs import get_city_by_type_transport_and_address_point
|
# try:
|
||||||
# from RoutesApp.models import Route
|
# # body = request.body
|
||||||
# from ReferenceDataApp.models import Airport, City
|
# # data = json.loads(body)
|
||||||
|
# # if 'head' not in data or 'body' not in data or 'id' not in data:
|
||||||
|
# # return JsonResponse(status=400, data={"message": "Invalid data format"})
|
||||||
|
# # user_id = data['id']
|
||||||
|
# user = request.user
|
||||||
|
# payload = {'head': '123', 'body': 'qwerty'}
|
||||||
|
# send_user_notification(user=user, payload=payload, ttl=1000)
|
||||||
|
# return JsonResponse(status=200, data={"message": "Web push successful"})
|
||||||
|
# except TypeError:
|
||||||
|
# return JsonResponse(status=500, data={"message": "An error occurred"})
|
||||||
|
|
||||||
|
# routes = Route.objects.all()
|
||||||
#
|
#
|
||||||
# res = None
|
# for route in routes:
|
||||||
|
# print(route.id)
|
||||||
|
# required_save = False
|
||||||
|
# if not route.from_city:
|
||||||
|
# route.from_city = get_city_by_type_transport_and_address_point(route.type_transport, route.from_address_point)
|
||||||
|
# required_save = True
|
||||||
#
|
#
|
||||||
# from_air = Airport.objects.get(iata_code='MSQ')
|
# if not route.to_city:
|
||||||
# to_air = Airport.objects.get(iata_code='SVO')
|
# route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
|
||||||
|
# route.to_address_point)
|
||||||
|
# required_save = True
|
||||||
#
|
#
|
||||||
# routes = [
|
# if required_save:
|
||||||
# Route(
|
# route.save()
|
||||||
# type_transport='road',
|
|
||||||
# departure_DT=datetime.now() + timedelta(days=7),
|
|
||||||
# arrival_DT=datetime.now() + timedelta(days=8),
|
|
||||||
# from_address_point=to_air.city.id,
|
|
||||||
# to_address_point=from_air.city.id,
|
|
||||||
# from_city=to_air.city,
|
|
||||||
# to_city=from_air.city,
|
|
||||||
# weight=item,
|
|
||||||
# phone='0987654321',
|
|
||||||
# owner=request.user
|
|
||||||
# ) for item in range(100)
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# routes = [
|
|
||||||
# Route(
|
|
||||||
# type_transport='avia',
|
|
||||||
# departure_DT=datetime(year=2024, month=9, day=1),
|
|
||||||
# arrival_DT=datetime(year=2024, month=9, day=3),
|
|
||||||
# from_address_point = from_air.id,
|
|
||||||
# to_address_point = to_air.id,
|
|
||||||
# from_city = from_air.city,
|
|
||||||
# to_city = to_air.city,
|
|
||||||
# weight = item,
|
|
||||||
# phone = '1234567890',
|
|
||||||
# owner = request.user
|
|
||||||
# ) for item in range(1000)
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# Route.objects.bulk_create(routes)
|
|
||||||
|
|
||||||
|
|
||||||
# from RoutesApp.search_matches import search_matches
|
|
||||||
# routes = Route.objects.filter()[:10]
|
|
||||||
# msg = search_matches(routes)
|
|
||||||
|
|
||||||
# from ReferenceDataApp.funcs import parse_data
|
|
||||||
# parse_data()
|
|
||||||
|
|
||||||
# from SubscribesApp.reports import send_mail_for_user_subscribes_that_is_going_to_finish
|
|
||||||
# send_mail_for_user_subscribes_that_is_going_to_finish()
|
|
||||||
|
|
||||||
if res:
|
|
||||||
if type(res) == str:
|
|
||||||
return HttpResponse(res)
|
|
||||||
else:
|
|
||||||
return res
|
|
||||||
|
|
||||||
return HttpResponse('finished')
|
return HttpResponse('finished')
|
||||||
|
|
||||||
@@ -143,57 +67,12 @@ def Page404(request, exeption=None):
|
|||||||
|
|
||||||
t = loader.get_template('404.html')
|
t = loader.get_template('404.html')
|
||||||
try:
|
try:
|
||||||
res = get_inter_http_response(t, Dict, request)
|
res = get_inter_http_respose(t, Dict, request)
|
||||||
return HttpResponse(res, status=404)
|
return HttpResponse(res, status=404)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return HttpResponse(str(e))
|
return HttpResponse(str(e))
|
||||||
|
|
||||||
def LandingMoverPage(request):
|
|
||||||
|
|
||||||
from .init_options import init_options
|
|
||||||
init_options()
|
|
||||||
|
|
||||||
|
|
||||||
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
|
|
||||||
|
|
||||||
page, is_created = StaticPage.objects.get_or_create(url='landing_mover')
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'page': page,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
breadcrumbs_Dict = {
|
|
||||||
}
|
|
||||||
Dict.update({'breadcrumbs': breadcrumbs_Dict})
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_mover_landing_page.html')
|
|
||||||
return get_inter_http_response(t, Dict, request)
|
|
||||||
|
|
||||||
|
|
||||||
def LandingCustomerPage(request):
|
|
||||||
|
|
||||||
from .init_options import init_options
|
|
||||||
init_options()
|
|
||||||
|
|
||||||
|
|
||||||
print(f'LOCALE_PATHS = {str(settings.LOCALE_PATHS)}')
|
|
||||||
|
|
||||||
page, is_created = StaticPage.objects.get_or_create(url='landing_customer')
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'page': page,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
breadcrumbs_Dict = {
|
|
||||||
}
|
|
||||||
Dict.update({'breadcrumbs': breadcrumbs_Dict})
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_customer_landing_page.html')
|
|
||||||
return get_inter_http_response(t, Dict, request)
|
|
||||||
|
|
||||||
|
|
||||||
def MainPage(request):
|
def MainPage(request):
|
||||||
@@ -225,14 +104,14 @@ def MainPage(request):
|
|||||||
Dict.update({'breadcrumbs': breadcrumbs_Dict})
|
Dict.update({'breadcrumbs': breadcrumbs_Dict})
|
||||||
|
|
||||||
t = loader.get_template('pages/p_main.html')
|
t = loader.get_template('pages/p_main.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def StaticPageView(request, url):
|
def StaticPageView(request, url):
|
||||||
from RoutesApp.forms import RouteForm
|
from RoutesApp.forms import RouteForm
|
||||||
from SubscribesApp.funcs import get_subscribes_w_options
|
from SubscribesApp.funcs import get_subsribes_w_options
|
||||||
|
|
||||||
Dict = {}
|
Dict = {}
|
||||||
|
|
||||||
@@ -254,7 +133,7 @@ def StaticPageView(request, url):
|
|||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if url in ['for_movers', 'for_customers']:
|
if url in ['for_movers', 'for_customers']:
|
||||||
subscribes, all_options = get_subscribes_w_options()
|
subscribes, all_options = get_subsribes_w_options()
|
||||||
Dict.update({
|
Dict.update({
|
||||||
'subscribes': subscribes,
|
'subscribes': subscribes,
|
||||||
})
|
})
|
||||||
@@ -269,11 +148,8 @@ def StaticPageView(request, url):
|
|||||||
'page': page,
|
'page': page,
|
||||||
})
|
})
|
||||||
|
|
||||||
# from PushMessages.views import send_push
|
|
||||||
# send_push(user=request.user, title='title', text='text')
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_static_page.html')
|
t = loader.get_template('pages/p_static_page.html')
|
||||||
return get_inter_http_response(t, Dict, request)
|
return get_inter_http_respose(t, Dict, request)
|
||||||
# return HttpResponse(t.render(Dict, request))
|
# return HttpResponse(t.render(Dict, request))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import json
|
|||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
|
||||||
|
|
||||||
|
|
||||||
def get_key_Dict():
|
def get_key_Dict():
|
||||||
@@ -19,9 +18,6 @@ def get_key_Dict():
|
|||||||
return Dict
|
return Dict
|
||||||
|
|
||||||
def send_push(user, title, text, url=None, button_name=None, img=None):
|
def send_push(user, title, text, url=None, button_name=None, img=None):
|
||||||
if not check_option_in_cur_user_subscribe(user, 'push уведомления'):
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# body = request.body
|
# body = request.body
|
||||||
# data = json.loads(body)
|
# data = json.loads(body)
|
||||||
|
|||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
celery -A TWB.celery:app worker -l info
|
||||||
|
|
||||||
|
celery -A TWB.celery:app beat -l info
|
||||||
@@ -2,7 +2,6 @@ from django.contrib import admin
|
|||||||
from sets.admin import Admin_Trans_BaseModel
|
from sets.admin import Admin_Trans_BaseModel
|
||||||
from .models import *
|
from .models import *
|
||||||
from modeltranslation.admin import TranslationAdmin
|
from modeltranslation.admin import TranslationAdmin
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
class Admin_Country(Admin_Trans_BaseModel):
|
class Admin_Country(Admin_Trans_BaseModel):
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
@@ -11,20 +10,11 @@ class Admin_Country(Admin_Trans_BaseModel):
|
|||||||
'fields': [
|
'fields': [
|
||||||
'name', 'enable', 'short_code', 'code',
|
'name', 'enable', 'short_code', 'code',
|
||||||
]
|
]
|
||||||
}],
|
}]
|
||||||
[_('Дополнительно'), {
|
|
||||||
'classes': ['wide', 'collapse'],
|
|
||||||
'fields': (
|
|
||||||
'timezone',
|
|
||||||
'geo_lat', 'geo_lon',
|
|
||||||
'json_data',
|
|
||||||
)
|
|
||||||
}],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'name', 'name_en', 'name_ru',
|
'id', 'name', 'name_en', 'name_ru',
|
||||||
'timezone',
|
|
||||||
'short_code', 'code',
|
'short_code', 'code',
|
||||||
'enable', 'area_id', 'parsing_finished_DT',
|
'enable', 'area_id', 'parsing_finished_DT',
|
||||||
'order', 'modifiedDT', 'createDT']
|
'order', 'modifiedDT', 'createDT']
|
||||||
@@ -32,35 +22,18 @@ class Admin_Country(Admin_Trans_BaseModel):
|
|||||||
admin.site.register(Country, Admin_Country)
|
admin.site.register(Country, Admin_Country)
|
||||||
|
|
||||||
class Admin_City(Admin_Trans_BaseModel):
|
class Admin_City(Admin_Trans_BaseModel):
|
||||||
|
|
||||||
def cur_dt(self, obj):
|
|
||||||
if obj.timezone:
|
|
||||||
return obj.get_current_datetime()
|
|
||||||
else:
|
|
||||||
return '-'
|
|
||||||
cur_dt.short_description = 'текущее время'
|
|
||||||
|
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
[None, {
|
[None, {
|
||||||
'classes': ['wide'],
|
'classes': ['wide'],
|
||||||
'fields': [
|
'fields': [
|
||||||
'name', 'enable', 'country',
|
'name', 'enable', 'country',
|
||||||
]
|
]
|
||||||
}],
|
}]
|
||||||
[_('Дополнительно'), {
|
|
||||||
'classes': ['wide', 'collapse'],
|
|
||||||
'fields': (
|
|
||||||
'timezone',
|
|
||||||
'geo_lat', 'geo_lon',
|
|
||||||
'json_data',
|
|
||||||
)
|
|
||||||
}],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'name', 'name_en', 'name_ru',
|
'id', 'name', 'name_en', 'name_ru',
|
||||||
'country',
|
'country',
|
||||||
'timezone', 'cur_dt',
|
|
||||||
'enable', 'area_id', 'parsing_finished_DT',
|
'enable', 'area_id', 'parsing_finished_DT',
|
||||||
'order', 'modifiedDT', 'createDT']
|
'order', 'modifiedDT', 'createDT']
|
||||||
search_fields = ['id', 'name_en', 'name_ru', 'country__name']
|
search_fields = ['id', 'name_en', 'name_ru', 'country__name']
|
||||||
@@ -77,21 +50,12 @@ class Admin_Airport(Admin_Trans_BaseModel):
|
|||||||
'international_name',
|
'international_name',
|
||||||
# 'area_id'
|
# 'area_id'
|
||||||
]
|
]
|
||||||
}],
|
}]
|
||||||
[_('Дополнительно'), {
|
|
||||||
'classes': ['wide', 'collapse'],
|
|
||||||
'fields': (
|
|
||||||
'timezone',
|
|
||||||
'geo_lat', 'geo_lon',
|
|
||||||
'json_data',
|
|
||||||
)
|
|
||||||
}],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'name', 'name_en', 'name_ru',
|
'id', 'name', 'name_en', 'name_ru',
|
||||||
'city', 'iata_code', 'icao_code',
|
'city', 'iata_code', 'icao_code',
|
||||||
'timezone',
|
|
||||||
'international_name',
|
'international_name',
|
||||||
'enable', 'area_id', 'parsing_finished_DT',
|
'enable', 'area_id', 'parsing_finished_DT',
|
||||||
'order', 'modifiedDT', 'createDT']
|
'order', 'modifiedDT', 'createDT']
|
||||||
|
|||||||
@@ -3,45 +3,24 @@ from .models import *
|
|||||||
import hashlib, json
|
import hashlib, json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from timezonefinder import TimezoneFinder
|
|
||||||
|
|
||||||
tzf = TimezoneFinder()
|
|
||||||
|
|
||||||
def search_cities_in_db(search_str):
|
def search_cities_in_db(search_str):
|
||||||
res_data = []
|
|
||||||
|
|
||||||
|
|
||||||
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
|
Q_obj = Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
|
||||||
Q(country__name_en__icontains=search_str) | Q(country__name_ru__icontains=search_str)
|
Q(country__name_en__icontains=search_str) | Q(country__name_ru__icontains=search_str)
|
||||||
objs = City.objects.filter(Q_obj)
|
res_data = City.objects.filter(Q_obj).values('id', 'name', 'country__name')
|
||||||
if objs:
|
|
||||||
ids = objs.values_list('id', flat=True)
|
|
||||||
objs_wo_tz = objs.filter(timezone=None)
|
|
||||||
for item in objs_wo_tz:
|
|
||||||
item.get_n_save_timezone()
|
|
||||||
res_data = City.objects.filter(id__in=ids).values(
|
|
||||||
'id', 'name', 'country__name', 'timezone'
|
|
||||||
)
|
|
||||||
|
|
||||||
return list(res_data)
|
return list(res_data)
|
||||||
|
|
||||||
def search_airports_in_db(search_str):
|
def search_airports_in_db(search_str):
|
||||||
res_data = []
|
|
||||||
Q_obj = Q(iata_code__icontains=search_str) | \
|
Q_obj = Q(iata_code__icontains=search_str) | \
|
||||||
Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
|
Q(name_en__icontains=search_str) | Q(name_ru__icontains=search_str) | \
|
||||||
Q(city__name_en__icontains=search_str) | Q(city__name_ru__icontains=search_str) | \
|
Q(city__name_en__icontains=search_str) | Q(city__name_ru__icontains=search_str) | \
|
||||||
Q(city__country__name_en__icontains=search_str) | \
|
Q(city__country__name_en__icontains=search_str) | \
|
||||||
Q(city__country__name_ru__icontains=search_str)
|
Q(city__country__name_ru__icontains=search_str)
|
||||||
objs = Airport.objects.filter(Q_obj)
|
res_data = Airport.objects.filter(Q_obj).values('id', 'name', 'iata_code', 'city__name', 'city__country__name')
|
||||||
if objs:
|
|
||||||
ids = objs.values_list('id', flat=True)
|
|
||||||
objs_wo_tz = objs.filter(city__timezone=None)
|
|
||||||
for item in objs_wo_tz:
|
|
||||||
item.city.get_n_save_timezone()
|
|
||||||
|
|
||||||
res_data = Airport.objects.filter(id__in=ids).values(
|
|
||||||
'id', 'name', 'iata_code',
|
|
||||||
'city__name', 'city__country__name', 'city__timezone'
|
|
||||||
)
|
|
||||||
|
|
||||||
return list(res_data)
|
return list(res_data)
|
||||||
|
|
||||||
|
|
||||||
@@ -78,39 +57,25 @@ def create_airports_by_airportsList(airportsList, city=None):
|
|||||||
if airport_Dict['iata']:
|
if airport_Dict['iata']:
|
||||||
kwargs.update({'iata_code': airport_Dict['iata']})
|
kwargs.update({'iata_code': airport_Dict['iata']})
|
||||||
airport = Airport.objects.get(**kwargs)
|
airport = Airport.objects.get(**kwargs)
|
||||||
if airport.geo_lat and airport.geo_lon and not airport.timezone:
|
|
||||||
airport.timezone = tzf.timezone_at(
|
|
||||||
lng=float(airport.geo_lon), lat=float(airport.geo_lat))
|
|
||||||
airport.modifiedDT = datetime.now()
|
|
||||||
airport.save()
|
|
||||||
print(f'airport {airport.international_name} - {airport.timezone}')
|
|
||||||
except Airport.DoesNotExist:
|
except Airport.DoesNotExist:
|
||||||
print(f' - - {airport_Dict["iata"]} не найден в БД > добавляем')
|
print(f' - - {airport_Dict["iata"]} не найден в БД > добавляем')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'error = {str(e)}')
|
print(f'error = {str(e)}')
|
||||||
|
|
||||||
if not airport:
|
if not airport:
|
||||||
geo_lat = float(airport_Dict['@lat'])
|
|
||||||
geo_lon = float(airport_Dict['@lon'])
|
|
||||||
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
|
|
||||||
print(f'airport {airport_Dict["int_name"]} - {tz}')
|
|
||||||
|
|
||||||
airport_kwargs = {
|
airport_kwargs = {
|
||||||
'city': city,
|
'city': city,
|
||||||
|
|
||||||
# 'name_ru': airport_Dict['name:ru'],
|
# 'name_ru': airport_Dict['name:ru'],
|
||||||
# 'name_en': airport_Dict['name:en'],
|
# 'name_en': airport_Dict['name:en'],
|
||||||
'timezone': tz,
|
|
||||||
|
|
||||||
'geo_lat': str(geo_lat),
|
'geo_lat': str(airport_Dict['@lat']),
|
||||||
'geo_lon': str(geo_lon),
|
'geo_lon': str(airport_Dict['@lon']),
|
||||||
|
|
||||||
'international_name': airport_Dict['int_name'],
|
'international_name': airport_Dict['int_name'],
|
||||||
|
|
||||||
'iata_code': airport_Dict['iata'],
|
'iata_code': airport_Dict['iata'],
|
||||||
'icao_code': airport_Dict['icao'],
|
'icao_code': airport_Dict['icao'],
|
||||||
|
|
||||||
'modifiedDT': datetime.now(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if airport_Dict['name:ru']:
|
if airport_Dict['name:ru']:
|
||||||
@@ -154,10 +119,7 @@ def parse_data():
|
|||||||
|
|
||||||
country = Country.objects.get(**kwargs)
|
country = Country.objects.get(**kwargs)
|
||||||
|
|
||||||
if (country.parsing_finished_DT
|
if country.parsing_finished_DT and (datetime.now() - country.parsing_finished_DT).days < 30:
|
||||||
and (datetime.now() - country.parsing_finished_DT).days < 30
|
|
||||||
and country.timezone
|
|
||||||
):
|
|
||||||
print(f' + {country.name} - существует в БД, не требует парсинга')
|
print(f' + {country.name} - существует в БД, не требует парсинга')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -232,12 +194,6 @@ def parse_data():
|
|||||||
else:
|
else:
|
||||||
print(f'error = {str(e)}')
|
print(f'error = {str(e)}')
|
||||||
|
|
||||||
geo_lat = float(city_Dict['@lat'])
|
|
||||||
geo_lon = float(city_Dict['@lon'])
|
|
||||||
tz = tzf.timezone_at(lng=geo_lon, lat=geo_lat)
|
|
||||||
if not city or not city.timezone:
|
|
||||||
print(f'city {city_Dict["name:en"]} - {tz}')
|
|
||||||
|
|
||||||
# собираем данные
|
# собираем данные
|
||||||
city_kwargs = {
|
city_kwargs = {
|
||||||
'country': country,
|
'country': country,
|
||||||
@@ -245,11 +201,8 @@ def parse_data():
|
|||||||
# 'name_ru': city_Dict['name:ru'],
|
# 'name_ru': city_Dict['name:ru'],
|
||||||
# 'name_en': city_Dict['name:en'],
|
# 'name_en': city_Dict['name:en'],
|
||||||
|
|
||||||
'timezone': tz,
|
'geo_lat': str(city_Dict['@lat']),
|
||||||
|
'geo_lon': str(city_Dict['@lon']),
|
||||||
'geo_lat': str(geo_lat),
|
|
||||||
'geo_lon': str(geo_lon),
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if city_Dict['name:ru']:
|
if city_Dict['name:ru']:
|
||||||
@@ -279,12 +232,8 @@ def parse_data():
|
|||||||
hash_data = hashlib.md5(json.dumps(country_Dict, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
|
hash_data = hashlib.md5(json.dumps(country_Dict, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
|
||||||
country.add_node_to_json_data({'hash': hash_data})
|
country.add_node_to_json_data({'hash': hash_data})
|
||||||
|
|
||||||
if not country.timezone:
|
|
||||||
country.timezone = tzf.timezone_at(lng=float(country.geo_lon), lat=float(country.geo_lat))
|
|
||||||
print(f'country {country.name} - {country.timezone}')
|
|
||||||
|
|
||||||
if 'parsing_status' in country_Dict and country_Dict['parsing_status'] == 'finished':
|
if 'parsing_status' in country_Dict and country_Dict['parsing_status'] == 'finished':
|
||||||
country.parsing_finished_DT = datetime.now()
|
country.parsing_finished_DT = datetime.now()
|
||||||
country.save()
|
country.save(update_fields=['parsing_finished_DT'])
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@@ -13,8 +13,7 @@ from django.template.loader import render_to_string
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
import json
|
import json
|
||||||
from GeneralApp.funcs import get_inter_http_response
|
from GeneralApp.funcs import get_inter_http_respose
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
|
|
||||||
def get_address_point_ajax(request):
|
def get_address_point_ajax(request):
|
||||||
from .funcs import search_cities_in_db, search_airports_in_db
|
from .funcs import search_cities_in_db, search_airports_in_db
|
||||||
@@ -22,9 +21,6 @@ def get_address_point_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -56,12 +52,10 @@ def get_address_point_ajax(request):
|
|||||||
item['fullname'] = f'{item["iata_code"]} - {item["name"]}'
|
item['fullname'] = f'{item["iata_code"]} - {item["name"]}'
|
||||||
item['city_name'] = item['city__name']
|
item['city_name'] = item['city__name']
|
||||||
item['country_name'] = item['city__country__name']
|
item['country_name'] = item['city__country__name']
|
||||||
item['city_DT'] = datetime.now(tz=pytz.timezone(item['city__timezone']))
|
|
||||||
else:
|
else:
|
||||||
item['city_name'] = item['name']
|
item['city_name'] = item['name']
|
||||||
item['country_name'] = item['country__name']
|
item['country_name'] = item['country__name']
|
||||||
item['fullname'] = f'{item["city_name"]} / {item["country_name"]}'
|
item['fullname'] = f'{item["city_name"]} / {item["country_name"]}'
|
||||||
item['city_DT'] = datetime.now(tz=pytz.timezone(item['timezone']))
|
|
||||||
html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
|
html = f"{html}{render_to_string('widgets/w_ac_input_address_point.html', item)}"
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
@@ -70,8 +64,6 @@ def get_address_point_ajax(request):
|
|||||||
'res_search_list': html
|
'res_search_list': html
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-07-12 17:23
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('ReferenceDataApp', '0005_remove_airport_parsing_finished_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='airport',
|
|
||||||
name='timezone',
|
|
||||||
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='city',
|
|
||||||
name='timezone',
|
|
||||||
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='country',
|
|
||||||
name='timezone',
|
|
||||||
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='Часовая зона'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
import pytz
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from BaseModels.base_models import BaseModel
|
from BaseModels.base_models import BaseModel
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class Country(BaseModel):
|
class Country(BaseModel):
|
||||||
international_name = models.CharField(max_length=250, verbose_name=_('Международное название'), blank=True, null=True)
|
international_name = models.CharField(max_length=250, verbose_name=_('Международное название'), blank=True, null=True)
|
||||||
@@ -17,8 +15,6 @@ class Country(BaseModel):
|
|||||||
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
|
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
|
||||||
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
|
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
|
||||||
|
|
||||||
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
|
|
||||||
|
|
||||||
area_id = models.BigIntegerField(blank=True, null=True)
|
area_id = models.BigIntegerField(blank=True, null=True)
|
||||||
|
|
||||||
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
||||||
@@ -50,8 +46,6 @@ class City(BaseModel):
|
|||||||
|
|
||||||
area_id = models.BigIntegerField(blank=True, null=True)
|
area_id = models.BigIntegerField(blank=True, null=True)
|
||||||
|
|
||||||
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
|
|
||||||
|
|
||||||
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@@ -60,17 +54,6 @@ class City(BaseModel):
|
|||||||
else:
|
else:
|
||||||
return f'{self.id}'
|
return f'{self.id}'
|
||||||
|
|
||||||
def get_n_save_timezone(self):
|
|
||||||
from ReferenceDataApp.funcs import tzf
|
|
||||||
self.timezone = tzf.timezone_at(lng=float(self.geo_lon), lat=float(self.geo_lat))
|
|
||||||
self.save(update_fields=['timezone'])
|
|
||||||
return self.timezone
|
|
||||||
|
|
||||||
def get_current_datetime(self):
|
|
||||||
if not self.timezone:
|
|
||||||
self.timezone = self.get_n_save_timezone()
|
|
||||||
return datetime.now(tz=pytz.timezone(self.timezone))
|
|
||||||
|
|
||||||
def get_country_n_city_str(self):
|
def get_country_n_city_str(self):
|
||||||
country = _('Неизвестно')
|
country = _('Неизвестно')
|
||||||
city = self.name
|
city = self.name
|
||||||
@@ -100,8 +83,6 @@ class Airport(BaseModel):
|
|||||||
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
|
geo_lat = models.CharField(max_length=20, verbose_name=_('GPS широта'), blank=True, null=True)
|
||||||
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
|
geo_lon = models.CharField(max_length=20, verbose_name=_('GPS долгота'), blank=True, null=True)
|
||||||
|
|
||||||
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
|
|
||||||
|
|
||||||
area_id = models.BigIntegerField(blank=True, null=True)
|
area_id = models.BigIntegerField(blank=True, null=True)
|
||||||
|
|
||||||
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
||||||
|
|||||||
@@ -3,33 +3,17 @@ from .models import *
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
class Admin_Route(Admin_Trans_BaseModel):
|
class Admin_Route(Admin_Trans_BaseModel):
|
||||||
readonly_fields = [
|
|
||||||
# 'highlight_end_DT',
|
|
||||||
'rising_DT'
|
|
||||||
]
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'owner_type',
|
'id', 'owner_type', 'receive_msg_by_email', 'type_transport', 'cargo_type',
|
||||||
'rising_DT',
|
|
||||||
'receive_msg_by_email', 'type_transport', 'cargo_type',
|
|
||||||
'departure_DT', 'from_city', 'from_place',
|
'departure_DT', 'from_city', 'from_place',
|
||||||
'arrival_DT', 'to_city', 'to_place', 'owner',
|
'arrival_DT', 'to_city', 'to_place', 'owner',
|
||||||
'order', 'modifiedDT', 'createDT'
|
'order', 'modifiedDT', 'createDT'
|
||||||
]
|
]
|
||||||
list_editable = ['rising_DT']
|
|
||||||
|
|
||||||
list_display_links = ['id']
|
list_display_links = ['id']
|
||||||
|
|
||||||
list_filter = [
|
list_filter = ['owner_type', 'type_transport', 'cargo_type', 'from_place', 'arrival_DT', 'modifiedDT', 'createDT']
|
||||||
'owner_type', 'type_transport',
|
search_fields = ['owner__first_name', 'owner__last_name']
|
||||||
'rising_DT',
|
|
||||||
'cargo_type',
|
|
||||||
'from_place', 'arrival_DT',
|
|
||||||
'modifiedDT', 'createDT'
|
|
||||||
]
|
|
||||||
|
|
||||||
search_fields = [
|
|
||||||
'owner__first_name', 'owner__last_name', 'from_city__name', 'to_city__name', 'owner__email'
|
|
||||||
]
|
|
||||||
raw_id_fields = ['from_city', 'to_city']
|
raw_id_fields = ['from_city', 'to_city']
|
||||||
|
|
||||||
admin.site.register(Route,Admin_Route)
|
admin.site.register(Route,Admin_Route)
|
||||||
|
|||||||
@@ -50,9 +50,6 @@ def routeForm_assign_choices_by_type_transport(form, type_transport):
|
|||||||
class RouteForm(forms.ModelForm):
|
class RouteForm(forms.ModelForm):
|
||||||
from_address_point_txt = forms.CharField(required=True)
|
from_address_point_txt = forms.CharField(required=True)
|
||||||
to_address_point_txt = forms.CharField(required=True)
|
to_address_point_txt = forms.CharField(required=True)
|
||||||
departure_DT = forms.DateTimeField(required=True, input_formats=['%d.%m.%Y %H:%M'])
|
|
||||||
arrival_DT = forms.DateTimeField(required=True, input_formats=['%d.%m.%Y %H:%M'])
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Route
|
model = Route
|
||||||
exclude = [
|
exclude = [
|
||||||
@@ -64,6 +61,8 @@ class RouteForm(forms.ModelForm):
|
|||||||
# print('check')
|
# print('check')
|
||||||
cleaned_data = super(RouteForm, self).clean()
|
cleaned_data = super(RouteForm, self).clean()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if 'phone' in cleaned_data and 'phone' in cleaned_data:
|
if 'phone' in cleaned_data and 'phone' in cleaned_data:
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
from BaseModels.mailSender import techSendMail
|
|
||||||
from GeneralApp.funcs_options import get_mail_send_options
|
|
||||||
from .models import *
|
from .models import *
|
||||||
from .forms import *
|
from .forms import *
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from django.db.models import F, Q
|
|
||||||
|
|
||||||
elements_on_page = 25
|
elements_on_page = 25
|
||||||
|
|
||||||
@@ -111,9 +108,9 @@ def get_profile_new_route_page_html(request, data):
|
|||||||
return html
|
return html
|
||||||
|
|
||||||
|
|
||||||
# def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
|
def get_country_n_city_str_by_type_transport_and_address_point(type_transport, address_point):
|
||||||
# city = get_city_by_type_transport_and_address_point(type_transport, address_point)
|
city = get_city_by_type_transport_and_address_point(type_transport, address_point)
|
||||||
# return city.get_country_n_city_str()
|
return city.get_country_n_city_str()
|
||||||
|
|
||||||
|
|
||||||
def get_city_by_type_transport_and_address_point(type_transport, address_point):
|
def get_city_by_type_transport_and_address_point(type_transport, address_point):
|
||||||
@@ -129,16 +126,6 @@ def get_city_by_type_transport_and_address_point(type_transport, address_point):
|
|||||||
print(msg)
|
print(msg)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_city_by_address_point(address_point):
|
|
||||||
from ReferenceDataApp.models import Airport, City
|
|
||||||
|
|
||||||
try:
|
|
||||||
return City.objects.get(id=address_point)
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'get_city_by_address_point Error = {str(e)}, address_point = {address_point}'
|
|
||||||
print(msg)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_profile_my_routes_page_content_html(request):
|
def get_profile_my_routes_page_content_html(request):
|
||||||
routes_Dict = get_routes_Dict(request.user)
|
routes_Dict = get_routes_Dict(request.user)
|
||||||
@@ -147,11 +134,6 @@ def get_profile_my_routes_page_content_html(request):
|
|||||||
print(msg)
|
print(msg)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
if user_subscribe:
|
|
||||||
routes_Dict.update(user_subscribe.remains_route_adding_options())
|
|
||||||
|
|
||||||
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
|
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
|
||||||
return html
|
return html
|
||||||
|
|
||||||
@@ -172,7 +154,6 @@ def get_routes_Dict(user=None, data=None):
|
|||||||
'owner': user
|
'owner': user
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
from_el = None
|
from_el = None
|
||||||
to_el = None
|
to_el = None
|
||||||
|
|
||||||
@@ -222,19 +203,16 @@ def get_routes_Dict(user=None, data=None):
|
|||||||
):
|
):
|
||||||
kwargs.update({key: val})
|
kwargs.update({key: val})
|
||||||
|
|
||||||
if key == 'from_address_point': # в from_address_point всегда город
|
if key == 'from_address_point':
|
||||||
# city = get_city_by_type_transport_and_address_point(type_transport, val)
|
city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||||
city = get_city_by_address_point(val)
|
|
||||||
kwargs.update({f'from_city': city})
|
kwargs.update({f'from_city': city})
|
||||||
|
|
||||||
|
|
||||||
res_Dict.update({
|
res_Dict.update({
|
||||||
'from_address_point_txt': city.get_country_n_city_str()
|
'from_address_point_txt': city.get_country_n_city_str()
|
||||||
})
|
})
|
||||||
|
|
||||||
if key == 'to_address_point': # в to_address_point всегда город
|
if key == 'to_address_point':
|
||||||
# city = get_city_by_type_transport_and_address_point(type_transport, val)
|
city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||||
city = get_city_by_address_point(val)
|
|
||||||
kwargs.update({f'to_city': city})
|
kwargs.update({f'to_city': city})
|
||||||
res_Dict.update({
|
res_Dict.update({
|
||||||
'to_address_point_txt': city.get_country_n_city_str()
|
'to_address_point_txt': city.get_country_n_city_str()
|
||||||
@@ -245,41 +223,9 @@ def get_routes_Dict(user=None, data=None):
|
|||||||
if key == 'to_el':
|
if key == 'to_el':
|
||||||
to_el = int(val)
|
to_el = int(val)
|
||||||
|
|
||||||
# rising_routes = Route.objects.filter(
|
routes = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
|
||||||
# **kwargs,
|
|
||||||
# ).exclude(
|
|
||||||
# rising_DT=None
|
|
||||||
# ).order_by(
|
|
||||||
# '-rising_DT', '-departure_DT', '-arrival_DT', '-modifiedDT'
|
|
||||||
# )
|
|
||||||
# routes = Route.objects.exclude(
|
|
||||||
# rising_DT=None
|
|
||||||
# ).filter(
|
|
||||||
# departure_DT__lt=datetime.now()
|
|
||||||
# )
|
|
||||||
# routes.update(
|
|
||||||
# rising_DT=None
|
|
||||||
# )
|
|
||||||
|
|
||||||
routes_rising_off = Route.objects.exclude(rising_DT=None).filter(
|
|
||||||
Q(rising_DT__lt=datetime.now() - timedelta(days=1)) | Q(departure_DT__lt=datetime.now())
|
|
||||||
)
|
|
||||||
if routes_rising_off:
|
|
||||||
routes_rising_off.update(rising_DT=None)
|
|
||||||
|
|
||||||
routes = Route.objects.filter(
|
|
||||||
**kwargs
|
|
||||||
).order_by(
|
|
||||||
F('rising_DT').desc(nulls_last=True),
|
|
||||||
# '-rising_DT',
|
|
||||||
'-departure_DT', '-arrival_DT', '-modifiedDT'
|
|
||||||
)
|
|
||||||
|
|
||||||
routes_count = routes.count()
|
routes_count = routes.count()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if from_el and to_el:
|
if from_el and to_el:
|
||||||
routes = routes[from_el:to_el]
|
routes = routes[from_el:to_el]
|
||||||
elif from_el:
|
elif from_el:
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ from django.urls import path
|
|||||||
# from AuthApp.import_funcs import *
|
# from AuthApp.import_funcs import *
|
||||||
from .js_views import *
|
from .js_views import *
|
||||||
|
|
||||||
# /routes/
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('change_route/<int:route_id>/', create_or_change_route_ajax, name='change_route_ajax'),
|
path('change_route/<int:route_id>/', create_or_change_route_ajax, name='change_route_ajax'),
|
||||||
path('create_or_change_route/', create_or_change_route_ajax, name='create_or_change_route_ajax'),
|
path('create_or_change_route/', create_or_change_route_ajax, name='create_or_change_route_ajax'),
|
||||||
@@ -16,7 +14,4 @@ urlpatterns = [
|
|||||||
path('get_routes/', get_my_routes_ajax, name='get_my_routes_ajax'),
|
path('get_routes/', get_my_routes_ajax, name='get_my_routes_ajax'),
|
||||||
path('find_routes/', find_routes_ajax, name='find_routes_ajax'),
|
path('find_routes/', find_routes_ajax, name='find_routes_ajax'),
|
||||||
|
|
||||||
path('raise_route/', raise_route_ajax, name='raise_route_ajax'),
|
|
||||||
path('highlight_route/', highlight_route_ajax, name='highlight_route_ajax'),
|
|
||||||
|
|
||||||
]
|
]
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import json
|
import json
|
||||||
from copy import deepcopy
|
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
@@ -11,114 +10,17 @@ from django.template import loader, RequestContext
|
|||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from BaseModels.mailSender import techSendMail
|
from BaseModels.mailSender import techSendMail
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from .forms import *
|
from .forms import *
|
||||||
from .funcs import *
|
from .funcs import *
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
|
||||||
|
|
||||||
|
|
||||||
def highlight_route_ajax(request):
|
|
||||||
if request.method != 'POST':
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
data = request.POST
|
|
||||||
if not data and request.body:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
|
|
||||||
if not data or not 'route_id' in data:
|
|
||||||
msg = _('Недостаточно данных')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
try:
|
|
||||||
route = Route.objects.get(owner=request.user, id=data['route_id'])
|
|
||||||
except Route.DoesNotExist:
|
|
||||||
msg = _('Не найден маршрут')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
if not route.get_permission_for_highlight():
|
|
||||||
msg = _('Нет доступа к выделению')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
user_subscribe.used_route_highlight_count += 1
|
|
||||||
user_subscribe.save(update_fields=['used_route_highlight_count'])
|
|
||||||
|
|
||||||
|
|
||||||
route.highlight_color = '#FF0000'
|
|
||||||
highlight_hours = user_subscribe.get_highlight_hours()
|
|
||||||
route.highlight_end_DT = datetime.now() + timedelta(hours=highlight_hours)
|
|
||||||
route.save(update_fields=['highlight_color', 'highlight_end_DT'])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'route': route,
|
|
||||||
}
|
|
||||||
|
|
||||||
html = render_to_string('widgets/routes/w_my_route.html', Dict, request=request)
|
|
||||||
|
|
||||||
res_Dict = {
|
|
||||||
'html': html
|
|
||||||
}
|
|
||||||
res_Dict.update(user_subscribe.remains_route_adding_options())
|
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
def raise_route_ajax(request):
|
|
||||||
if request.method != 'POST':
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
data = request.POST
|
|
||||||
if not data and request.body:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
|
|
||||||
if not data or not 'route_id' in data:
|
|
||||||
msg = _('Недостаточно данных')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
try:
|
|
||||||
route = Route.objects.get(owner=request.user, id=data['route_id'])
|
|
||||||
except Route.DoesNotExist:
|
|
||||||
msg = _('Не найден маршрут')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
if not route.get_permission_for_raise():
|
|
||||||
msg = _('Нет доступных поднятий')
|
|
||||||
return JsonResponse({'errors': msg})
|
|
||||||
|
|
||||||
route.rising_DT = datetime.now()
|
|
||||||
route.save(update_fields=['rising_DT'])
|
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
user_subscribe.used_route_rising_count += 1
|
|
||||||
user_subscribe.save(update_fields=['used_route_rising_count'])
|
|
||||||
|
|
||||||
res_Dict = {'status': 'ok'}
|
|
||||||
res_Dict.update(user_subscribe.remains_route_adding_options())
|
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
def del_route_ajax(request):
|
def del_route_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
|
||||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
@@ -138,8 +40,6 @@ def del_route_ajax(request):
|
|||||||
'html': html
|
'html': html
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -154,11 +54,6 @@ def edit_route_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
|
||||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
|
|
||||||
Dict = {}
|
Dict = {}
|
||||||
@@ -193,13 +88,7 @@ def edit_route_ajax(request):
|
|||||||
return JsonResponse({'errors': msg})
|
return JsonResponse({'errors': msg})
|
||||||
|
|
||||||
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
||||||
res_Dict = {
|
return JsonResponse({'html': html}, status=200)
|
||||||
'html': html,
|
|
||||||
'btn_title': _('Сохранить изменения')
|
|
||||||
}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -209,10 +98,6 @@ def edit_route_ajax(request):
|
|||||||
def new_route_view_ajax(request):
|
def new_route_view_ajax(request):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
|
||||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
# form = RouteForm()
|
# form = RouteForm()
|
||||||
# Dict = {
|
# Dict = {
|
||||||
@@ -238,10 +123,7 @@ def new_route_view_ajax(request):
|
|||||||
|
|
||||||
|
|
||||||
# html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
# html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
||||||
res_Dict = {'html': html}
|
return JsonResponse({'html': html}, status=200)
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
def find_routes_ajax(request):
|
def find_routes_ajax(request):
|
||||||
@@ -250,8 +132,6 @@ def find_routes_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
|
||||||
@@ -265,7 +145,6 @@ def find_routes_ajax(request):
|
|||||||
if 'errors' in routes_Dict:
|
if 'errors' in routes_Dict:
|
||||||
return JsonResponse(routes_Dict, status=400)
|
return JsonResponse(routes_Dict, status=400)
|
||||||
|
|
||||||
|
|
||||||
if routes_Dict['routes']:
|
if routes_Dict['routes']:
|
||||||
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
|
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
|
||||||
else:
|
else:
|
||||||
@@ -278,8 +157,6 @@ def find_routes_ajax(request):
|
|||||||
# 'form': RouteForm(initial=data)
|
# 'form': RouteForm(initial=data)
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -298,30 +175,11 @@ def get_my_routes_ajax(request):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
data = request.POST.dict()
|
|
||||||
if not data and request.body:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
routes_Dict = get_routes_Dict(request.user)
|
||||||
if not request.user or request.user.is_anonymous:
|
|
||||||
msg = (f'get_my_routes_ajax not have user - user={str(request.user)}<br>'
|
|
||||||
f'data={str(data)}<br>'
|
|
||||||
f'request={str(request)}')
|
|
||||||
mail_sets = get_mail_send_options()
|
|
||||||
techSendMail(mail_sets, msg)
|
|
||||||
|
|
||||||
routes_Dict = get_routes_Dict(request.user, data)
|
|
||||||
if 'errors' in routes_Dict:
|
if 'errors' in routes_Dict:
|
||||||
return JsonResponse(routes_Dict, status=400)
|
return JsonResponse(routes_Dict, status=400)
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
if user_subscribe:
|
|
||||||
routes_Dict.update(user_subscribe.remains_route_adding_options())
|
|
||||||
|
|
||||||
|
|
||||||
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
|
html = render_to_string('blocks/profile/b_my_routes.html', routes_Dict, request=request)
|
||||||
|
|
||||||
@@ -329,8 +187,6 @@ def get_my_routes_ajax(request):
|
|||||||
'html': html
|
'html': html
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -350,13 +206,7 @@ def create_or_change_route_ajax(request, route_id=None):
|
|||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
|
||||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
Dict = {}
|
Dict = {}
|
||||||
route_old_Dict = None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
@@ -371,7 +221,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
|||||||
if route:
|
if route:
|
||||||
form = RouteForm(data, instance=route)
|
form = RouteForm(data, instance=route)
|
||||||
Dict.update({'route': route})
|
Dict.update({'route': route})
|
||||||
route_old_Dict = deepcopy(route.__dict__)
|
|
||||||
else:
|
else:
|
||||||
form = RouteForm(data)
|
form = RouteForm(data)
|
||||||
|
|
||||||
@@ -392,16 +241,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
|||||||
if obj.to_address_point:
|
if obj.to_address_point:
|
||||||
obj.to_city = get_city_by_type_transport_and_address_point(obj.type_transport, obj.to_address_point)
|
obj.to_city = get_city_by_type_transport_and_address_point(obj.type_transport, obj.to_address_point)
|
||||||
|
|
||||||
if route_old_Dict:
|
|
||||||
if route_old_Dict['highlight_color'] != obj.highlight_color:
|
|
||||||
obj.highlight_color = route_old_Dict['highlight_color']
|
|
||||||
|
|
||||||
if route_old_Dict['highlight_end_DT'] != obj.highlight_end_DT:
|
|
||||||
obj.highlight_end_DT = route_old_Dict['highlight_end_DT']
|
|
||||||
|
|
||||||
if route_old_Dict['rising_DT'] != obj.rising_DT:
|
|
||||||
obj.rising_DT = route_old_Dict['rising_DT']
|
|
||||||
|
|
||||||
obj.owner = request.user
|
obj.owner = request.user
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
||||||
@@ -409,11 +248,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
|||||||
|
|
||||||
routes_Dict = get_routes_Dict(request.user)
|
routes_Dict = get_routes_Dict(request.user)
|
||||||
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
if user_subscribe:
|
|
||||||
routes_Dict.update(user_subscribe.remains_route_adding_options())
|
|
||||||
|
|
||||||
if 'errors' in routes_Dict:
|
if 'errors' in routes_Dict:
|
||||||
form.errors.update(routes_Dict['errors'])
|
form.errors.update(routes_Dict['errors'])
|
||||||
Dict.update({'form': form})
|
Dict.update({'form': form})
|
||||||
@@ -427,8 +261,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
|||||||
'route_id': route_id
|
'route_id': route_id
|
||||||
}
|
}
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
return JsonResponse(res_Dict)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -15,16 +15,21 @@ class Command(BaseCommand):
|
|||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from SubscribesApp.funcs import finish_user_subscribes, extension_free_subscribes
|
from ...search_matches import search_matches
|
||||||
extension_free_subscribes()
|
msg = search_matches()
|
||||||
finish_user_subscribes()
|
if msg:
|
||||||
|
print(msg)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'every_day_start fail = {str(e)}'
|
msg = f'every_1hour_start search_matches fail = {str(e)}'
|
||||||
print(msg)
|
print(msg)
|
||||||
techSendMail(mail_sets, msg, title='every_day_start fail')
|
techSendMail(mail_sets, msg, title='every_1hour_start search_matches')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if msg:
|
||||||
|
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
|
||||||
|
|
||||||
|
|
||||||
# if msg:
|
|
||||||
# techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
|
|
||||||
|
|
||||||
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')
|
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-06-03 01:31
|
|
||||||
|
|
||||||
import colorfield.fields
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RoutesApp', '0005_route_from_city_route_to_city'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='route',
|
|
||||||
name='rising_DT',
|
|
||||||
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата и время последнего поднятия'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='route',
|
|
||||||
name='select_color',
|
|
||||||
field=colorfield.fields.ColorField(blank=True, default=None, image_field=None, max_length=25, null=True, samples=None, verbose_name='Цвет выделения'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='route',
|
|
||||||
name='arrival_DT',
|
|
||||||
field=models.DateTimeField(verbose_name='Дата и время прибытия'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='route',
|
|
||||||
name='departure_DT',
|
|
||||||
field=models.DateTimeField(verbose_name='Дата и время выезда'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-06-03 02:30
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RoutesApp', '0006_route_rising_dt_route_select_color_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='route',
|
|
||||||
old_name='select_color',
|
|
||||||
new_name='highlight_color',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-08-13 13:28
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RoutesApp', '0007_rename_select_color_route_highlight_color'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='route',
|
|
||||||
name='highlight_end_DT',
|
|
||||||
field=models.DateTimeField(blank=True, null=True, verbose_name='Дата и время окончания выделения'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-11-12 10:51
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('RoutesApp', '0008_route_highlight_end_dt'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='route',
|
|
||||||
name='phone',
|
|
||||||
field=models.CharField(blank=True, null=True, verbose_name='Укажите номер для связи'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from BaseModels.base_models import BaseModel
|
from BaseModels.base_models import BaseModel
|
||||||
from colorfield.fields import ColorField
|
|
||||||
|
|
||||||
|
|
||||||
type_transport_choices = [
|
type_transport_choices = [
|
||||||
@@ -39,8 +38,8 @@ class Route(BaseModel):
|
|||||||
|
|
||||||
type_transport = models.CharField(
|
type_transport = models.CharField(
|
||||||
choices=type_transport_choices, default='', verbose_name=_('Выберите способ перевозки'))
|
choices=type_transport_choices, default='', verbose_name=_('Выберите способ перевозки'))
|
||||||
departure_DT = models.DateTimeField(verbose_name=_('Дата и время выезда'))
|
departure_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время выезда'))
|
||||||
arrival_DT = models.DateTimeField(verbose_name=_('Дата и время прибытия'))
|
arrival_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время прибытия'))
|
||||||
from_address_point = models.IntegerField(verbose_name=_('Пункт выезда'))
|
from_address_point = models.IntegerField(verbose_name=_('Пункт выезда'))
|
||||||
to_address_point = models.IntegerField(verbose_name=_('Пункт приезда'))
|
to_address_point = models.IntegerField(verbose_name=_('Пункт приезда'))
|
||||||
from_city = models.ForeignKey(
|
from_city = models.ForeignKey(
|
||||||
@@ -57,25 +56,12 @@ class Route(BaseModel):
|
|||||||
verbose_name=_('Куда можете доставить?'))
|
verbose_name=_('Куда можете доставить?'))
|
||||||
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', verbose_name=_('Могу перевезти'))
|
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', verbose_name=_('Могу перевезти'))
|
||||||
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'))
|
weight = models.IntegerField(verbose_name=_('Укажите вес до (кг)'))
|
||||||
phone = models.CharField(verbose_name=_('Укажите номер для связи'), blank=True, null=True)
|
phone = models.CharField(verbose_name=_('Укажите номер для связи'))
|
||||||
extra_phone = models.CharField(verbose_name=_('Дополнительный номер'), blank=True, null=True)
|
extra_phone = models.CharField(verbose_name=_('Дополнительный номер'), blank=True, null=True)
|
||||||
receive_msg_by_email = models.BooleanField(default=False, verbose_name=_('Получать уведомления по E-mail'))
|
receive_msg_by_email = models.BooleanField(default=False, verbose_name=_('Получать уведомления по E-mail'))
|
||||||
receive_msg_by_sms = models.BooleanField(default=False, verbose_name=_('Получать уведомления по SMS'))
|
receive_msg_by_sms = models.BooleanField(default=False, verbose_name=_('Получать уведомления по SMS'))
|
||||||
owner = models.ForeignKey(User, verbose_name=_('Владелец'), related_name='rel_routes_for_owner', on_delete=models.CASCADE)
|
owner = models.ForeignKey(User, verbose_name=_('Владелец'), related_name='rel_routes_for_owner', on_delete=models.CASCADE)
|
||||||
|
|
||||||
rising_DT = models.DateTimeField(
|
|
||||||
verbose_name=_('Дата и время последнего поднятия'),
|
|
||||||
blank=True, null=True
|
|
||||||
)
|
|
||||||
highlight_color = ColorField(
|
|
||||||
verbose_name=_('Цвет выделения'),
|
|
||||||
blank=True, null=True
|
|
||||||
)
|
|
||||||
highlight_end_DT = models.DateTimeField(
|
|
||||||
verbose_name=_('Дата и время окончания выделения'),
|
|
||||||
blank=True, null=True
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.name:
|
if self.name:
|
||||||
return f'{self.name}'
|
return f'{self.name}'
|
||||||
@@ -88,29 +74,6 @@ class Route(BaseModel):
|
|||||||
verbose_name_plural = _(u'Маршруты')
|
verbose_name_plural = _(u'Маршруты')
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
|
||||||
def get_permission_for_raise(self):
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(self.owner)
|
|
||||||
if not user_subscribe:
|
|
||||||
return False
|
|
||||||
data_Dict = user_subscribe.remains_route_adding_options()
|
|
||||||
if data_Dict['remains_route_rising_count'] > 0:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_permission_for_highlight(self):
|
|
||||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
|
||||||
user_subscribe = get_cur_user_subscribe(self.owner)
|
|
||||||
if not user_subscribe:
|
|
||||||
return False
|
|
||||||
data_Dict = user_subscribe.remains_route_adding_options()
|
|
||||||
if data_Dict['remains_route_highlight_count'] > 0:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def from_country_n_city_str(self):
|
def from_country_n_city_str(self):
|
||||||
res = _('Неизвестно')
|
res = _('Неизвестно')
|
||||||
if self.from_city:
|
if self.from_city:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
|
|||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib, techSendMail
|
from BaseModels.mailSender import admin_send_mail_by_SMTPlib, techSendMail
|
||||||
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
|
||||||
|
|
||||||
|
|
||||||
def get_Dict_for_send_msgs(kwargs, search_owner_type):
|
def get_Dict_for_send_msgs(kwargs, search_owner_type):
|
||||||
@@ -36,9 +36,6 @@ def send_push_message_for_found_matches_routes(route, data_Dict):
|
|||||||
if not route.owner.is_authenticated:
|
if not route.owner.is_authenticated:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not check_option_in_cur_user_subscribe(route.owner, 'push уведомления'):
|
|
||||||
return False
|
|
||||||
|
|
||||||
from PushMessages.views import send_push
|
from PushMessages.views import send_push
|
||||||
title = 'Мы нашли исполнителя по Вашему объявлению!'
|
title = 'Мы нашли исполнителя по Вашему объявлению!'
|
||||||
text = 'Для просмотра результата нажмите на кнопку ниже'
|
text = 'Для просмотра результата нажмите на кнопку ниже'
|
||||||
@@ -59,7 +56,7 @@ def send_mail_found_matches_routes(route, data_Dict):
|
|||||||
|
|
||||||
|
|
||||||
mail_sets = get_mail_send_options()
|
mail_sets = get_mail_send_options()
|
||||||
to = [route.owner.email]
|
to = [route.owner.email, 'web@syncsystems.net']
|
||||||
subject = _('Мы нашли исполнителя по Вашему объявлению!')
|
subject = _('Мы нашли исполнителя по Вашему объявлению!')
|
||||||
res = admin_send_mail_by_SMTPlib(
|
res = admin_send_mail_by_SMTPlib(
|
||||||
mail_sets,
|
mail_sets,
|
||||||
@@ -67,13 +64,6 @@ def send_mail_found_matches_routes(route, data_Dict):
|
|||||||
from_email=mail_sets['sender_email'], to=to,
|
from_email=mail_sets['sender_email'], to=to,
|
||||||
html_content=html
|
html_content=html
|
||||||
)
|
)
|
||||||
to = ['web@syncsystems.net']
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -91,11 +81,8 @@ def search_matches(for_routes=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
check_fields = [
|
check_fields = [
|
||||||
'type_transport', 'departure_DT', 'arrival_DT',
|
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
|
||||||
# 'from_address_point', 'to_address_point',
|
'from_place', 'to_place', 'cargo_type', 'weight'
|
||||||
'from_place', 'to_place',
|
|
||||||
'cargo_type', 'weight',
|
|
||||||
'from_city', 'to_city',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if for_routes:
|
if for_routes:
|
||||||
@@ -116,20 +103,11 @@ def search_matches(for_routes=None):
|
|||||||
kwargs.update({f"{field_name}__date": field_val.date()})
|
kwargs.update({f"{field_name}__date": field_val.date()})
|
||||||
elif field_name == 'weight':
|
elif field_name == 'weight':
|
||||||
# print(field_name)
|
# print(field_name)
|
||||||
|
params.update({f"{field_name}": field_val})
|
||||||
if route.owner_type == 'mover':
|
if route.owner_type == 'mover':
|
||||||
# params.update({f"{field_name}__lte": field_val})
|
|
||||||
kwargs.update({f"{field_name}__lte": field_val})
|
kwargs.update({f"{field_name}__lte": field_val})
|
||||||
else:
|
else:
|
||||||
# params.update({f"{field_name}__gte": field_val})
|
|
||||||
kwargs.update({f"{field_name}__gte": field_val})
|
kwargs.update({f"{field_name}__gte": field_val})
|
||||||
elif field_name == 'from_city':
|
|
||||||
params.update({'from_address_point': field_val.id})
|
|
||||||
kwargs.update({field_name: field_val})
|
|
||||||
elif field_name == 'to_city':
|
|
||||||
params.update({'to_address_point': field_val.id})
|
|
||||||
kwargs.update({field_name: field_val})
|
|
||||||
# elif field_name in ['from_address_point', 'to_address_point']:
|
|
||||||
# kwargs.update({field_name: field_val})
|
|
||||||
else:
|
else:
|
||||||
kwargs.update({field_name: field_val})
|
kwargs.update({field_name: field_val})
|
||||||
params.update({field_name: field_val})
|
params.update({field_name: field_val})
|
||||||
@@ -148,38 +126,13 @@ def search_matches(for_routes=None):
|
|||||||
if found_routes:
|
if found_routes:
|
||||||
msg = f'found routes for send messages = {found_routes.count()}'
|
msg = f'found routes for send messages = {found_routes.count()}'
|
||||||
|
|
||||||
data_Dict = None
|
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
|
||||||
try:
|
msg = send_push_message_for_found_matches_routes(route, data_Dict)
|
||||||
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
|
if msg:
|
||||||
except Exception as e:
|
log += msg
|
||||||
msg = f'<br>\n! search_matches Error get_Dict_for_send_msgs = {str(e)}'
|
msg = send_mail_found_matches_routes(route, data_Dict)
|
||||||
print(msg)
|
if msg:
|
||||||
log += msg
|
log += msg
|
||||||
|
|
||||||
if data_Dict and check_option_in_cur_user_subscribe(
|
|
||||||
route.owner, 'push уведомления'
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
msg = send_push_message_for_found_matches_routes(route, data_Dict)
|
|
||||||
if msg:
|
|
||||||
log += msg
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'<br>\n! search_matches Error send_push_message_for_found_matches_routes = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
log += msg
|
|
||||||
|
|
||||||
if data_Dict and check_option_in_cur_user_subscribe(
|
|
||||||
route.owner,
|
|
||||||
'уведомление на e-mail о появлении перевозчика по заданным критериям'
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
msg = send_mail_found_matches_routes(route, data_Dict)
|
|
||||||
if msg:
|
|
||||||
log += msg
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'<br>\n! search_matches Error send_mail_found_matches_routes = {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
log += msg
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'<br>\n! search_matches Error = {str(e)}'
|
msg = f'<br>\n! search_matches Error = {str(e)}'
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from django.utils.translation import gettext as _
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from .funcs import *
|
from .funcs import *
|
||||||
from .forms import *
|
from .forms import *
|
||||||
from GeneralApp.funcs import get_inter_http_response
|
from GeneralApp.funcs import get_inter_http_respose
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -19,48 +19,42 @@ from GeneralApp.funcs import get_inter_http_response
|
|||||||
def route_search_results_View(request):
|
def route_search_results_View(request):
|
||||||
|
|
||||||
Dict = {}
|
Dict = {}
|
||||||
data = {}
|
data = None
|
||||||
|
|
||||||
try:
|
if request.GET:
|
||||||
|
data = request.GET.dict()
|
||||||
|
|
||||||
if request.GET:
|
routes_Dict = get_routes_Dict(data=data)
|
||||||
data = request.GET.dict()
|
if routes_Dict:
|
||||||
|
Dict = {
|
||||||
|
'routes': routes_Dict['routes'],
|
||||||
|
'last_block': routes_Dict['last_block'],
|
||||||
|
'show_filter_and_results': True,
|
||||||
|
'owner_type': data['owner_type'],
|
||||||
|
'last_el': routes_Dict['last_el'],
|
||||||
|
'page_type': 'routes',
|
||||||
|
'next_page_els_count': routes_Dict['next_page_els_count'],
|
||||||
|
}
|
||||||
|
if 'from_address_point_txt' in routes_Dict:
|
||||||
|
data.update({'from_address_point_txt': routes_Dict['from_address_point_txt']})
|
||||||
|
if 'to_address_point_txt' in routes_Dict:
|
||||||
|
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']})
|
||||||
|
Dict.update({'route_form': RouteForm(initial=data)})
|
||||||
|
|
||||||
routes_Dict = get_routes_Dict(data=data)
|
title = _('Результат поиска маршрутов')
|
||||||
if routes_Dict:
|
if 'from_address_point_txt' in data:
|
||||||
Dict = {
|
title = f'{title} из {data["from_address_point_txt"]}'
|
||||||
'routes': routes_Dict['routes'],
|
if 'to_address_point_txt' in data:
|
||||||
'last_block': routes_Dict['last_block'],
|
title = f'{title} в {data["to_address_point_txt"]}'
|
||||||
'show_filter_and_results': True,
|
|
||||||
'owner_type': data['owner_type'],
|
|
||||||
'last_el': routes_Dict['last_el'],
|
|
||||||
'page_type': 'routes',
|
|
||||||
'next_page_els_count': routes_Dict['next_page_els_count'],
|
|
||||||
}
|
|
||||||
if 'from_address_point_txt' in routes_Dict:
|
|
||||||
data.update({'from_address_point_txt': routes_Dict['from_address_point_txt']})
|
|
||||||
if 'to_address_point_txt' in routes_Dict:
|
|
||||||
data.update({'to_address_point_txt': routes_Dict['to_address_point_txt']})
|
|
||||||
Dict.update({'route_form': RouteForm(initial=data)})
|
|
||||||
|
|
||||||
title = _('Результат поиска маршрутов')
|
Dict.update({
|
||||||
if 'from_address_point_txt' in data:
|
'page': {
|
||||||
title = f'{title} из {data["from_address_point_txt"]}'
|
'title': title,
|
||||||
if 'to_address_point_txt' in data:
|
'description': title,
|
||||||
title = f'{title} в {data["to_address_point_txt"]}'
|
'keywords': title,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
Dict.update({
|
t = loader.get_template('pages/p_results_find_route.html')
|
||||||
'page': {
|
return get_inter_http_respose(t, Dict, request)
|
||||||
'title': title,
|
# return HttpResponse(t.render(Dict, request))
|
||||||
'description': title,
|
|
||||||
'keywords': title,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t = loader.get_template('pages/p_results_find_route.html')
|
|
||||||
return get_inter_http_response(t, Dict, request)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'!!! --- route_search_results_View Exception {str(e)}'
|
|
||||||
print(msg)
|
|
||||||
raise Http404
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
from django.db import models
|
|
||||||
|
|
||||||
# Create your models here.
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
This file demonstrates writing tests using the unittest module. These will pass
|
|
||||||
when you run "manage.py test".
|
|
||||||
|
|
||||||
Replace this with more appropriate tests for your application.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleTest(TestCase):
|
|
||||||
def test_basic_addition(self):
|
|
||||||
"""
|
|
||||||
Tests that 1 + 1 always equals 2.
|
|
||||||
"""
|
|
||||||
self.assertEqual(1 + 1, 2)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
from django.urls import include, path
|
|
||||||
from django.contrib.sitemaps import views as sitemaps_views
|
|
||||||
from django.views.decorators.cache import cache_page
|
|
||||||
|
|
||||||
from django.contrib.sitemaps.views import sitemap
|
|
||||||
from SitemapApp.views import sitemaps
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path('sitemap.xml', sitemap, {'sitemaps': sitemaps},
|
|
||||||
name='django.contrib.sitemaps.views.sitemap')
|
|
||||||
]
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
# coding=utf-8
|
|
||||||
from django.contrib.sitemaps import Sitemap
|
|
||||||
from django.urls import reverse
|
|
||||||
|
|
||||||
from BaseModels.mailSender import techSendMail
|
|
||||||
import json
|
|
||||||
from datetime import datetime, time, timezone
|
|
||||||
# from PageSetsApp.models import *
|
|
||||||
# from ArticlesApp.models import *
|
|
||||||
# from BaseModels.base_api_requests import base_api_request
|
|
||||||
# from tEsiteProj.settings import API_URL
|
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
|
|
||||||
limit_records = 1000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sitemaps = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protocol = 'https'
|
|
||||||
|
|
||||||
class sm_StaticPage(Sitemap):
|
|
||||||
changefreq = 'monthly'
|
|
||||||
priority = 1
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
from GeneralApp.models import StaticPage
|
|
||||||
return StaticPage.objects.filter(enable=True)
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
if item.url == 'main':
|
|
||||||
return reverse('main')
|
|
||||||
else:
|
|
||||||
return reverse('static_page', args=[item.url])
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
return obj.modifiedDT
|
|
||||||
|
|
||||||
sitemaps.update({'static_pages': sm_StaticPage})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class sm_ArticlesPage(Sitemap):
|
|
||||||
changefreq = 'daily'
|
|
||||||
priority = 2
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return ['']
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
return reverse('articles')
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
from ArticlesApp.models import ArticleModel
|
|
||||||
article = ArticleModel.objects.filter(enable=True).order_by('-modifiedDT').first()
|
|
||||||
if article:
|
|
||||||
return article.modifiedDT
|
|
||||||
else:
|
|
||||||
return datetime.now()
|
|
||||||
|
|
||||||
sitemaps.update({'articles_page': sm_ArticlesPage})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class sm_Article(Sitemap):
|
|
||||||
changefreq = 'yearly'
|
|
||||||
priority = 2
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
from ArticlesApp.views import ArticleModel
|
|
||||||
objs = ArticleModel.objects.filter(enable=True)
|
|
||||||
|
|
||||||
return objs
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
return reverse('article_one', args=[item.url])
|
|
||||||
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
return obj.modifiedDT
|
|
||||||
|
|
||||||
sitemaps.update({'article': sm_Article})
|
|
||||||
|
|
||||||
|
|
||||||
class sm_UserPage(Sitemap):
|
|
||||||
changefreq = 'yearly'
|
|
||||||
priority = 2
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
from ArticlesApp.views import UserPageModel
|
|
||||||
objs = UserPageModel.objects.filter(enable=True)
|
|
||||||
|
|
||||||
return objs
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
return reverse('user_page', args=[item.url])
|
|
||||||
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
return obj.modifiedDT
|
|
||||||
|
|
||||||
sitemaps.update({'user_page': sm_UserPage})
|
|
||||||
|
|
||||||
|
|
||||||
class sm_Registration(Sitemap):
|
|
||||||
changefreq = 'never'
|
|
||||||
priority = 1
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return ['']
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
return reverse('registration_page')
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
return datetime(2024, 6, 1)
|
|
||||||
|
|
||||||
sitemaps.update({'registration': sm_Registration})
|
|
||||||
|
|
||||||
|
|
||||||
class sm_Login(Sitemap):
|
|
||||||
changefreq = 'never'
|
|
||||||
priority = 1
|
|
||||||
i18n = True
|
|
||||||
protocol = protocol
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return ['']
|
|
||||||
|
|
||||||
def location(self, item):
|
|
||||||
return reverse('login_profile')
|
|
||||||
|
|
||||||
def lastmod(self, obj):
|
|
||||||
return datetime(2024, 6, 1)
|
|
||||||
|
|
||||||
sitemaps.update({'login': sm_Login})
|
|
||||||
@@ -42,20 +42,11 @@ class Admin_SubscribeOption(Admin_Trans_BaseModel):
|
|||||||
'enable'
|
'enable'
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
(None, {
|
|
||||||
'classes': ['wide'],
|
|
||||||
'fields': (
|
|
||||||
('allow_route_rising_count',),
|
|
||||||
('allow_route_highlight_count', 'route_highlight_hours'),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'enable',
|
'id', 'enable',
|
||||||
'name',
|
'name',
|
||||||
'allow_route_rising_count',
|
|
||||||
'allow_route_highlight_count', 'route_highlight_hours',
|
|
||||||
'order', 'modifiedDT', 'createDT'
|
'order', 'modifiedDT', 'createDT'
|
||||||
]
|
]
|
||||||
list_editable = ['enable']
|
list_editable = ['enable']
|
||||||
@@ -72,7 +63,7 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
|||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(None, {
|
||||||
'classes': ['wide'],
|
'classes': ['wide'],
|
||||||
'fields': ('enable',
|
'fields': ('name',
|
||||||
'user', 'subscribe',
|
'user', 'subscribe',
|
||||||
'last_paid_DT',
|
'last_paid_DT',
|
||||||
'paid_period_from_DT', 'paid_period_to_DT',
|
'paid_period_from_DT', 'paid_period_to_DT',
|
||||||
@@ -83,9 +74,8 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
list_display = [
|
list_display = [
|
||||||
'id', 'enable',
|
'id',
|
||||||
'name', 'user', 'subscribe',
|
'name', 'user', 'subscribe',
|
||||||
'used_route_rising_count', 'used_route_highlight_count',
|
|
||||||
'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
|
'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
|
||||||
'auto_continue', 'receive_finish_subscribe_msg',
|
'auto_continue', 'receive_finish_subscribe_msg',
|
||||||
'order', 'modifiedDT', 'createDT'
|
'order', 'modifiedDT', 'createDT'
|
||||||
@@ -98,7 +88,6 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
|||||||
'auto_continue', 'receive_finish_subscribe_msg',
|
'auto_continue', 'receive_finish_subscribe_msg',
|
||||||
'modifiedDT', 'createDT'
|
'modifiedDT', 'createDT'
|
||||||
]
|
]
|
||||||
list_editable = ['enable']
|
search_fields = ['name']
|
||||||
search_fields = ['name', 'id', 'user__email', 'user__first_name', 'user__last_name']
|
|
||||||
|
|
||||||
admin.site.register(SubscribeForUser,Admin_SubscribeForUser)
|
admin.site.register(SubscribeForUser,Admin_SubscribeForUser)
|
||||||
@@ -1,197 +1,41 @@
|
|||||||
from .models import *
|
from .models import *
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.translation import get_language, activate
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import json
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_subscribes_that_is_going_to_finish():
|
|
||||||
user_subscribes = SubscribeForUser.objects.filter(
|
|
||||||
enable=True,
|
|
||||||
subscribe__price__gt=0,
|
|
||||||
paid_period_to_DT__lt=datetime.now() + timedelta(days=3),
|
|
||||||
paid_period_to_DT__gt=datetime.now()
|
|
||||||
)
|
|
||||||
|
|
||||||
return user_subscribes
|
|
||||||
|
|
||||||
|
|
||||||
def extension_free_subscribes():
|
|
||||||
subscribe = get_null_price_subscribe()
|
|
||||||
if not subscribe:
|
|
||||||
return None
|
|
||||||
|
|
||||||
user_subscribes = SubscribeForUser.objects.filter(
|
|
||||||
enable=True,
|
|
||||||
subscribe=subscribe
|
|
||||||
)
|
|
||||||
for user_subscribe in user_subscribes:
|
|
||||||
user_subscribe.extension()
|
|
||||||
msg = f'{str(user_subscribe)} free subscribe extended'
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def finish_user_subscribes():
|
|
||||||
|
|
||||||
finished_user_subscribes = SubscribeForUser.objects.filter(
|
|
||||||
enable=True, paid_period_to_DT__lt=datetime.now()
|
|
||||||
)
|
|
||||||
finished_user_subscribes.update(enable=False)
|
|
||||||
for finished_user_subscribe in finished_user_subscribes:
|
|
||||||
msg = f'{str(finished_user_subscribe)} subscribe finished and switch to free'
|
|
||||||
print(msg)
|
|
||||||
subscribe_user_to_null_price_subscribe(finished_user_subscribe.user)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def create_subscribe_by_data(create_kwargs):
|
|
||||||
subscribe = create_kwargs['subscribe']
|
|
||||||
create_kwargs.update({
|
|
||||||
'paid_period_from_DT': datetime.now(),
|
|
||||||
'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
|
|
||||||
'enable': False
|
|
||||||
})
|
|
||||||
subscribe_for_user = SubscribeForUser.objects.create(**create_kwargs)
|
|
||||||
return subscribe_for_user
|
|
||||||
|
|
||||||
|
|
||||||
def check_option_in_cur_user_subscribe(user, option_name):
|
|
||||||
if not user or not user.is_active or not user.is_authenticated:
|
|
||||||
return False
|
|
||||||
|
|
||||||
user_subscribe = get_cur_user_subscribe(user)
|
|
||||||
try:
|
|
||||||
option = SubscribeOption.objects.get(
|
|
||||||
rel_subscribes_for_option=user_subscribe.subscribe,
|
|
||||||
name_ru__iexact=option_name
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
except SubscribeOption.DoesNotExist:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_null_price_subscribe():
|
|
||||||
subscribes_null_price = Subscribe.objects.filter(
|
|
||||||
enable=True,
|
|
||||||
price=0
|
|
||||||
)
|
|
||||||
if subscribes_null_price:
|
|
||||||
return subscribes_null_price[0]
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def subscribe_user_to_null_price_subscribe(user):
|
|
||||||
subscribe = get_null_price_subscribe()
|
|
||||||
if not subscribe:
|
|
||||||
return None
|
|
||||||
|
|
||||||
kwargs = {
|
|
||||||
'user': user,
|
|
||||||
'subscribe': subscribe,
|
|
||||||
}
|
|
||||||
|
|
||||||
subscribe_for_user = create_subscribe_by_data(kwargs)
|
|
||||||
subscribe_for_user = subscribe_for_user.activate()
|
|
||||||
|
|
||||||
return subscribe_for_user
|
|
||||||
|
|
||||||
|
|
||||||
def get_cur_user_subscribe(user):
|
def get_cur_user_subscribe(user):
|
||||||
|
|
||||||
if not user or not user.is_active or not user.is_authenticated:
|
user_subscribe = None
|
||||||
return None
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_subscribe = SubscribeForUser.objects.get(enable=True, user=user)
|
user_subscribe = SubscribeForUser.objects.get(user=user)
|
||||||
except SubscribeForUser.DoesNotExist:
|
except Exception as e:
|
||||||
user_subscribe = subscribe_user_to_null_price_subscribe(user)
|
pass
|
||||||
except SubscribeForUser.MultipleObjectsReturned:
|
|
||||||
user_subscribes = SubscribeForUser.objects.filter(enable=True, user=user).order_by('-paid_period_to_DT')
|
|
||||||
user_subscribe = user_subscribes[0]
|
|
||||||
user_subscribes.exclude(id=user_subscribe.id).delete()
|
|
||||||
|
|
||||||
return user_subscribe
|
return user_subscribe
|
||||||
|
|
||||||
|
|
||||||
def get_subscribes_w_options(user=None, check_subscribe_orders=False):
|
def get_subsribes_w_options():
|
||||||
all_options = SubscribeOption.objects.filter(enable=True)
|
all_options = SubscribeOption.objects.filter(enable=True)
|
||||||
subscribes = Subscribe.objects.filter(enable=True)
|
subscribes = Subscribe.objects.filter(enable=True)
|
||||||
for subscribe in subscribes:
|
for subscribe in subscribes:
|
||||||
subscribe_options_ids = subscribe.options.values_list('id', flat=True)
|
subscribe_options_ids = subscribe.options.values_list('id', flat=True)
|
||||||
subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
|
subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
|
||||||
if user and check_subscribe_orders:
|
|
||||||
order = subscribe.get_last_order(user)
|
|
||||||
if order and order.status not in ['charged']:
|
|
||||||
error = f'{order.status}'
|
|
||||||
if 'status' in order.json_data and 'failure_message' in order.json_data['status']:
|
|
||||||
error = f'{error} ({order.json_data["status"]["failure_message"]})'
|
|
||||||
subscribe.order_error = error
|
|
||||||
|
|
||||||
return subscribes, all_options
|
return subscribes, all_options
|
||||||
|
|
||||||
|
|
||||||
def check_n_enable_subscribe_by_order(order):
|
def get_profile_subscribe_page_content_html(request):
|
||||||
|
|
||||||
if order and order.enable:
|
|
||||||
if order.status == 'charged':
|
|
||||||
order = order.activate_subscribe_for_user()
|
|
||||||
|
|
||||||
return order
|
|
||||||
|
|
||||||
|
|
||||||
def get_profile_subscribe_page_content_Dict(request, check_orders_required=False):
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
# data = json.loads(request.body)
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
if request.body:
|
|
||||||
data = json.loads(request.body)
|
|
||||||
# check_orders_required = False
|
|
||||||
if data and 'check_orders_required' in data: #Требуется проверка статусов заказов
|
|
||||||
check_orders_required = data['check_orders_required']
|
|
||||||
# all_options = SubscribeOption.objects.filter(enable=True)
|
# all_options = SubscribeOption.objects.filter(enable=True)
|
||||||
|
subscribes, all_options = get_subsribes_w_options()
|
||||||
|
|
||||||
|
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
|
||||||
subscribes = []
|
if not subscribe_for_user:
|
||||||
subscribe_for_user = None
|
|
||||||
all_options = []
|
|
||||||
|
|
||||||
orders = None
|
|
||||||
if request.user and request.user.is_authenticated:
|
|
||||||
from BillingApp.funcs import get_orders_for_user, get_order_status
|
|
||||||
orders = get_orders_for_user(request.user)
|
|
||||||
if orders:
|
|
||||||
if check_orders_required:
|
|
||||||
for order in orders:
|
|
||||||
order = get_order_status(order)
|
|
||||||
order = check_n_enable_subscribe_by_order(order)
|
|
||||||
subscribe_for_user = order.subscribe_for_user
|
|
||||||
|
|
||||||
subscribes, all_options = get_subscribes_w_options(
|
|
||||||
request.user, check_subscribe_orders=True)
|
|
||||||
|
|
||||||
check_orders_required = False
|
|
||||||
else:
|
|
||||||
check_orders_required = True
|
|
||||||
|
|
||||||
if not subscribes:
|
|
||||||
subscribes, all_options = get_subscribes_w_options()
|
|
||||||
|
|
||||||
# if not subscribes_for_user:
|
|
||||||
subscribes_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
|
|
||||||
|
|
||||||
if not subscribes_for_user:
|
|
||||||
tpl_name = 'blocks/profile/b_subscribe_variants.html'
|
tpl_name = 'blocks/profile/b_subscribe_variants.html'
|
||||||
else:
|
else:
|
||||||
tpl_name = 'blocks/profile/b_subscribe_current.html'
|
tpl_name = 'blocks/profile/b_subscribe_current.html'
|
||||||
subscribe_for_user = subscribes_for_user[0]
|
subscribe_for_user = subscribe_for_user[0]
|
||||||
subscribe_options_ids = subscribe_for_user.subscribe.options.values_list('id', flat=True)
|
subscribe_options_ids = subscribe_for_user.subscribe.options.values_list('id', flat=True)
|
||||||
subscribe_for_user.subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
|
subscribe_for_user.subscribe.disabled_options = all_options.exclude(id__in=subscribe_options_ids)
|
||||||
|
|
||||||
@@ -202,14 +46,11 @@ def get_profile_subscribe_page_content_Dict(request, check_orders_required=False
|
|||||||
|
|
||||||
Dict = {
|
Dict = {
|
||||||
'subscribe_for_user': subscribe_for_user,
|
'subscribe_for_user': subscribe_for_user,
|
||||||
'subscribes': subscribes,
|
'subscribes': subscribes
|
||||||
}
|
}
|
||||||
|
|
||||||
html = render_to_string(tpl_name, Dict, request=request)
|
html = render_to_string(tpl_name, Dict, request=request)
|
||||||
return {
|
return html
|
||||||
'html': html,
|
|
||||||
'check_orders_required': check_orders_required,
|
|
||||||
}
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
|
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
|
||||||
|
|||||||
@@ -6,12 +6,9 @@ from .js_views import *
|
|||||||
from django.contrib.auth import views
|
from django.contrib.auth import views
|
||||||
from RoutesApp.js_views import new_route_view_ajax
|
from RoutesApp.js_views import new_route_view_ajax
|
||||||
|
|
||||||
# /subscribes/receive_finish_subscribe_msg/
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('show_cur_subscribe/', show_cur_subscribe_ajax, name='show_cur_subscribe_ajax'),
|
path('show_cur_subscribe/', show_cur_subscribe_ajax, name='show_cur_subscribe_ajax'),
|
||||||
path('subscribe_now/', subscribe_now_ajax, name='subscribe_now_ajax'),
|
path('subscribe_now/', subscribe_now_ajax, name='subscribe_now_ajax'),
|
||||||
path('receive_finish_subscribe_msg/', receive_finish_subscribe_msg_ajax, name='receive_finish_subscribe_msg_ajax'),
|
|
||||||
# path('create_ticket/', create_ticket_ajax, name='create_ticket_ajax'),
|
# path('create_ticket/', create_ticket_ajax, name='create_ticket_ajax'),
|
||||||
# path('support_show_chat_by_ticket/', support_show_chat_by_ticket_ajax, name='support_show_chat_by_ticket_ajax'),
|
# path('support_show_chat_by_ticket/', support_show_chat_by_ticket_ajax, name='support_show_chat_by_ticket_ajax'),
|
||||||
# # path('send_msg/', send_msg_ajax, name='send_msg_ajax'),
|
# # path('send_msg/', send_msg_ajax, name='send_msg_ajax'),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from django.shortcuts import render
|
|||||||
from uuid import uuid1
|
from uuid import uuid1
|
||||||
from .models import *
|
from .models import *
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.http import HttpResponse, Http404, JsonResponse, HttpResponseRedirect
|
from django.http import HttpResponse, Http404, JsonResponse
|
||||||
from django.template import loader, RequestContext
|
from django.template import loader, RequestContext
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from BaseModels.mailSender import techSendMail
|
from BaseModels.mailSender import techSendMail
|
||||||
@@ -16,80 +16,36 @@ import json
|
|||||||
from datetime import datetime, time, timedelta
|
from datetime import datetime, time, timedelta
|
||||||
from channels.layers import get_channel_layer
|
from channels.layers import get_channel_layer
|
||||||
from asgiref.sync import async_to_sync
|
from asgiref.sync import async_to_sync
|
||||||
from GeneralApp.funcs import get_and_set_lang
|
|
||||||
from django.shortcuts import redirect
|
|
||||||
|
|
||||||
|
|
||||||
def receive_finish_subscribe_msg_ajax(request):
|
|
||||||
if request.method != 'POST':
|
|
||||||
raise Http404
|
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
@login_required(login_url='/profile/login/')
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
data = json.loads(request.body)
|
|
||||||
|
|
||||||
user_subscribe = get_cur_user_subscribe(request.user)
|
|
||||||
user_subscribe.receive_finish_subscribe_msg = data['receive_finish_subscribe_msg']
|
|
||||||
user_subscribe.save(update_fields=['receive_finish_subscribe_msg'])
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
msg = f'msg_send_after_subscribe_end_ajax Exception = {str(e)}'
|
|
||||||
return JsonResponse({'error': msg}, status=400)
|
|
||||||
|
|
||||||
res_Dict = {'status': user_subscribe.receive_finish_subscribe_msg}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
|
||||||
def subscribe_now_ajax(request):
|
def subscribe_now_ajax(request):
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
|
|
||||||
subscribe = Subscribe.objects.get(id=data['subscribe_id'])
|
subscribe = Subscribe.objects.get(id=data['subscribe_id'])
|
||||||
|
|
||||||
kwargs_for_order = {
|
kwargs = {
|
||||||
'user': request.user,
|
'user': request.user,
|
||||||
'subscribe': subscribe,
|
'subscribe': subscribe,
|
||||||
'currency': 'KZT',
|
'last_paid_DT': datetime.now(),
|
||||||
'sum': subscribe.price,
|
'paid_period_from_DT': datetime.now(),
|
||||||
|
'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
|
||||||
|
'receive_finish_subscribe_msg': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe_for_user = None
|
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
|
||||||
|
if subscribe_for_user:
|
||||||
if subscribe.price > 0:
|
subscribe_for_user.update(**kwargs)
|
||||||
from BillingApp.funcs import create_subscribe_order
|
subscribe_for_user = subscribe_for_user[0]
|
||||||
order = create_subscribe_order(kwargs_for_order)
|
|
||||||
if order:
|
|
||||||
res_Dict = {'redirect_url': order.pay_page}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
else:
|
else:
|
||||||
subscribe_for_user = subscribe_user_to_null_price_subscribe(request.user)
|
subscribe_for_user = SubscribeForUser.objects.create(**kwargs)
|
||||||
|
|
||||||
# kwargs = {
|
|
||||||
# 'user': request.user,
|
|
||||||
# 'subscribe': subscribe,
|
|
||||||
# 'last_paid_DT': datetime.now(),
|
|
||||||
# 'paid_period_from_DT': datetime.now(),
|
|
||||||
# 'paid_period_to_DT': datetime.now() + timedelta(hours=subscribe.period),
|
|
||||||
# 'receive_finish_subscribe_msg': True,
|
|
||||||
# }
|
|
||||||
# subscribe_for_user = SubscribeForUser.objects.filter(enable=True, user=request.user)
|
|
||||||
# if subscribe_for_user:
|
|
||||||
# subscribe_for_user.update(**kwargs)
|
|
||||||
# subscribe_for_user = subscribe_for_user[0]
|
|
||||||
|
|
||||||
if not subscribe_for_user:
|
if not subscribe_for_user:
|
||||||
tpl_name = 'blocks/profile/b_subscribe_variants.html'
|
tpl_name = 'blocks/profile/b_subscribe_variants.html'
|
||||||
@@ -108,30 +64,21 @@ def subscribe_now_ajax(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
html = render_to_string(tpl_name, Dict, request=request)
|
html = render_to_string(tpl_name, Dict, request=request)
|
||||||
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = {'html': html}
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
|
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
|
||||||
return JsonResponse({'error': msg}, status=400)
|
return JsonResponse({'error': msg}, status=400)
|
||||||
|
|
||||||
|
|
||||||
@login_required()#login_url='/profile/login/')
|
@login_required(login_url='/profile/login/')
|
||||||
def show_cur_subscribe_ajax(request):
|
def show_cur_subscribe_ajax(request):
|
||||||
|
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
lang = get_and_set_lang(request)
|
html = get_profile_subscribe_page_content_html(request)
|
||||||
|
return JsonResponse({'html': html}, status=200)
|
||||||
res_Dict = get_profile_subscribe_page_content_Dict(request)
|
|
||||||
|
|
||||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
|
||||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
|
||||||
return JsonResponse(res_Dict)
|
|
||||||
|
|
||||||
# try:
|
# try:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-06-02 12:58
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('SubscribesApp', '0003_alter_subscribe_bg_color_alter_subscribe_text_color'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeforuser',
|
|
||||||
name='used_route_rising_count',
|
|
||||||
field=models.IntegerField(default=0, verbose_name='Использовано поднятий объявлений'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeforuser',
|
|
||||||
name='used_route_select_count',
|
|
||||||
field=models.IntegerField(default=0, verbose_name='Использовано выделений объявлений'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeoption',
|
|
||||||
name='allow_route_rising_count',
|
|
||||||
field=models.IntegerField(default=0, verbose_name='Количество поднятий объявлений'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeoption',
|
|
||||||
name='allow_route_select_count',
|
|
||||||
field=models.IntegerField(default=0, verbose_name='Количество выделений объявлений'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-06-03 02:30
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('SubscribesApp', '0004_subscribeforuser_used_route_rising_count_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='subscribeforuser',
|
|
||||||
old_name='used_route_select_count',
|
|
||||||
new_name='used_route_highlight_count',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-06-03 02:43
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('SubscribesApp', '0005_rename_used_route_select_count_subscribeforuser_used_route_highlight_count'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RenameField(
|
|
||||||
model_name='subscribeoption',
|
|
||||||
old_name='allow_route_select_count',
|
|
||||||
new_name='allow_route_highlight_count',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 4.2.2 on 2024-08-13 13:28
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('SubscribesApp', '0006_rename_allow_route_select_count_subscribeoption_allow_route_highlight_count'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='subscribeoption',
|
|
||||||
name='route_highlight_hours',
|
|
||||||
field=models.IntegerField(default=24, verbose_name='Количество часов выделения цветом объявлений'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -1,29 +1,10 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Count, Sum, F
|
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
from BaseModels.base_models import BaseModel
|
from BaseModels.base_models import BaseModel
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from colorfield.fields import ColorField
|
from colorfield.fields import ColorField
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
# options_list 29.05.2024
|
|
||||||
# СМС уведомления
|
|
||||||
# push уведомления
|
|
||||||
# выделение заявки цветом (20 заявок) + 70 поднятий
|
|
||||||
# выделение заявок цветом (3 заявки) + 5 поднятий
|
|
||||||
# уведомление на e-mail о появлении перевозчика по заданным критериям
|
|
||||||
# размещение заявок
|
|
||||||
# просмотр контактов
|
|
||||||
|
|
||||||
class SubscribeOption(BaseModel):
|
class SubscribeOption(BaseModel):
|
||||||
|
|
||||||
allow_route_rising_count = models.IntegerField(
|
|
||||||
verbose_name=_('Количество поднятий объявлений') ,default=0)
|
|
||||||
allow_route_highlight_count = models.IntegerField(
|
|
||||||
verbose_name=_('Количество выделений объявлений'), default=0)
|
|
||||||
route_highlight_hours = models.IntegerField(
|
|
||||||
verbose_name=_('Количество часов выделения цветом объявлений'), default=24)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Опция подписки')
|
verbose_name = _('Опция подписки')
|
||||||
verbose_name_plural = _('Опции подписки')
|
verbose_name_plural = _('Опции подписки')
|
||||||
@@ -35,8 +16,7 @@ class Subscribe(BaseModel):
|
|||||||
|
|
||||||
price = models.FloatField(verbose_name='Стоимость', default=0)
|
price = models.FloatField(verbose_name='Стоимость', default=0)
|
||||||
options = models.ManyToManyField(
|
options = models.ManyToManyField(
|
||||||
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True,
|
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True, related_name='rel_subscribes_for_option'
|
||||||
related_name='rel_subscribes_for_option'
|
|
||||||
)
|
)
|
||||||
period_name = models.CharField(max_length=250, verbose_name=_('Название периода'))
|
period_name = models.CharField(max_length=250, verbose_name=_('Название периода'))
|
||||||
period = models.IntegerField(default=0, verbose_name=_('Длительность подписки в часах'))
|
period = models.IntegerField(default=0, verbose_name=_('Длительность подписки в часах'))
|
||||||
@@ -44,13 +24,6 @@ class Subscribe(BaseModel):
|
|||||||
bg_color = ColorField(default='#FFFFFF', verbose_name=_('Цвет фона'))
|
bg_color = ColorField(default='#FFFFFF', verbose_name=_('Цвет фона'))
|
||||||
text_color = ColorField(default='#000000', verbose_name=_('Цвет текста'))
|
text_color = ColorField(default='#000000', verbose_name=_('Цвет текста'))
|
||||||
|
|
||||||
def get_last_order(self, user):
|
|
||||||
order = None
|
|
||||||
orders = self.subscribe_orders_for_subscribe.filter(user=user, enable=True).order_by('-createDT')
|
|
||||||
if orders:
|
|
||||||
order = orders[0]
|
|
||||||
return order
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Подписка')
|
verbose_name = _('Подписка')
|
||||||
verbose_name_plural = _('Подписки')
|
verbose_name_plural = _('Подписки')
|
||||||
@@ -74,80 +47,6 @@ class SubscribeForUser(BaseModel):
|
|||||||
receive_finish_subscribe_msg = models.BooleanField(
|
receive_finish_subscribe_msg = models.BooleanField(
|
||||||
default=False, verbose_name=_('Получать сообщения о окончании периода'))
|
default=False, verbose_name=_('Получать сообщения о окончании периода'))
|
||||||
|
|
||||||
used_route_rising_count = models.IntegerField(verbose_name=_('Использовано поднятий объявлений'), default=0)
|
|
||||||
used_route_highlight_count = models.IntegerField(verbose_name=_('Использовано выделений объявлений'), default=0)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Пользовательская подписка')
|
verbose_name = _('Пользовательская подписка')
|
||||||
verbose_name_plural = _('Пользовательские подписки')
|
verbose_name_plural = _('Пользовательские подписки')
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
res = 'Подписка'
|
|
||||||
if self.subscribe:
|
|
||||||
res += f' {self.subscribe.name}'
|
|
||||||
if self.user:
|
|
||||||
res += f' для {self.user.username}'
|
|
||||||
|
|
||||||
if not res:
|
|
||||||
res += f' {str(self.id)}'
|
|
||||||
return res
|
|
||||||
|
|
||||||
def get_highlight_hours(self):
|
|
||||||
options = self.subscribe.options.filter(
|
|
||||||
allow_route_highlight_count__gt=0,
|
|
||||||
)
|
|
||||||
if options:
|
|
||||||
return options[0].route_highlight_hours
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def remains_route_adding_options(self):
|
|
||||||
total_data = SubscribeOption.objects.filter(
|
|
||||||
enable=True, rel_subscribes_for_option=self.subscribe
|
|
||||||
).aggregate(
|
|
||||||
total_route_rising_count = Coalesce(Sum('allow_route_rising_count'), 0),
|
|
||||||
total_route_highlight_count = Coalesce(Sum('allow_route_highlight_count'), 0),
|
|
||||||
)
|
|
||||||
total_data.update({
|
|
||||||
'used_route_rising_count': self.used_route_rising_count,
|
|
||||||
'used_route_highlight_count': self.used_route_highlight_count,
|
|
||||||
'remains_route_rising_count': total_data['total_route_rising_count'] - self.used_route_rising_count,
|
|
||||||
'remains_route_highlight_count': total_data['total_route_highlight_count'] - self.used_route_highlight_count,
|
|
||||||
})
|
|
||||||
return total_data
|
|
||||||
|
|
||||||
def get_days_to_finish(self):
|
|
||||||
days = (self.paid_period_to_DT - datetime.now()).days
|
|
||||||
return days
|
|
||||||
|
|
||||||
def extension(self, order=None):
|
|
||||||
if not order and self.subscribe.price > 0:
|
|
||||||
return {'error': 'not paid'}
|
|
||||||
|
|
||||||
if self.subscribe.price == 0:
|
|
||||||
self.activate(
|
|
||||||
paid_period_from_DT=datetime.now(),
|
|
||||||
paid_period_to_DT=datetime.now() + timedelta(hours=self.subscribe.period)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def activate(self, paid_period_from_DT=None, paid_period_to_DT=None):
|
|
||||||
self.enable = True
|
|
||||||
if paid_period_from_DT:
|
|
||||||
self.paid_period_from_DT = paid_period_from_DT
|
|
||||||
if paid_period_to_DT:
|
|
||||||
self.paid_period_to_DT = paid_period_to_DT
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
subscribes_for_user = SubscribeForUser.objects.filter(
|
|
||||||
user=self.user
|
|
||||||
).exclude(
|
|
||||||
id=self.id
|
|
||||||
)
|
|
||||||
subscribes_for_user.update(
|
|
||||||
enable=False,
|
|
||||||
used_route_rising_count=0,
|
|
||||||
used_route_highlight_count=0,
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
from .models import *
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from .funcs import *
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
def send_mail_for_user_subscribes_that_is_going_to_finish():
|
|
||||||
|
|
||||||
log = ''
|
|
||||||
|
|
||||||
user_subscribes = get_user_subscribes_that_is_going_to_finish()
|
|
||||||
|
|
||||||
for user_subscribe in user_subscribes:
|
|
||||||
if not user_subscribe.receive_finish_subscribe_msg:
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
|
|
||||||
from GeneralApp.funcs_options import get_options_by_opt_types, get_mail_send_options
|
|
||||||
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
|
|
||||||
|
|
||||||
subject = _('tripwb.com - Уведомление о скором окончании срока подписки')
|
|
||||||
|
|
||||||
Dict = {
|
|
||||||
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
|
||||||
'message_title': subject,
|
|
||||||
'user_subscribe': user_subscribe
|
|
||||||
}
|
|
||||||
Dict.update(sets)
|
|
||||||
|
|
||||||
html = render_to_string('mail/m_user_subscribes_that_is_going_to_finish.html', Dict)
|
|
||||||
from BaseModels.mailSender import admin_send_mail_by_SMTPlib
|
|
||||||
mail_sets = get_mail_send_options()
|
|
||||||
to = [user_subscribe.user.email]
|
|
||||||
res = admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
if res and type(res) == str:
|
|
||||||
print(res)
|
|
||||||
# log += f'\n{res}'
|
|
||||||
to = ['web@syncsystems.net', 'sa@a3-global.com', 'sysadmin.hax@gmail.com']
|
|
||||||
admin_send_mail_by_SMTPlib(
|
|
||||||
mail_sets,
|
|
||||||
subject=subject,
|
|
||||||
from_email=mail_sets['sender_email'], to=to,
|
|
||||||
html_content=html
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
msg = (f'send_mail_for_user_subscribes_that_is_going_to_finish '
|
|
||||||
f'for user {user_subscribe.user} '
|
|
||||||
f'Exception = {str(e)}')
|
|
||||||
print(msg)
|
|
||||||
log += f'\n{msg}'
|
|
||||||
|
|
||||||
return log
|
|
||||||
7
SubscribesApp/serializers.py
Normal file
7
SubscribesApp/serializers.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
|
||||||
|
class SubscribersSerializer(serializers.Serializer):
|
||||||
|
email = serializers.EmailField(error_messages={'invalid': 'Invalid email'})
|
||||||
|
email_notification = serializers.BooleanField()
|
||||||
|
auto_subscribe = serializers.BooleanField()
|
||||||
@@ -1 +0,0 @@
|
|||||||
__author__ = 'SDE'
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
__author__ = 'SDE'
|
|
||||||
|
|
||||||
from django import template
|
|
||||||
from django.template.defaultfilters import stringfilter
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
from django.core.serializers import serialize
|
|
||||||
from django.db.models.query import QuerySet
|
|
||||||
# import simplejson
|
|
||||||
from django.template import Library
|
|
||||||
from django.utils.html import mark_safe
|
|
||||||
|
|
||||||
# @register.filter('get_value_from_dict')
|
|
||||||
# def get_value_from_dict(dict_data, key):
|
|
||||||
# """
|
|
||||||
# usage example {{ your_dict|get_value_from_dict:your_key }}
|
|
||||||
# """
|
|
||||||
#
|
|
||||||
# if key in dict_data:
|
|
||||||
# res = dict_data[key]
|
|
||||||
# return res
|
|
||||||
#
|
|
||||||
# return False
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# @register.filter()
|
|
||||||
# def get_rows_count_by_cols_count(data, cols_count):
|
|
||||||
# rows_count = len(data) // cols_count
|
|
||||||
# if len(data) % cols_count:
|
|
||||||
# rows_count += 1
|
|
||||||
# return rows_count
|
|
||||||
#
|
|
||||||
# @register.filter()
|
|
||||||
# def get_numbers_list(from_el, to_el):
|
|
||||||
# res = range(from_el, to_el+1)
|
|
||||||
# return res
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def val_type(value):
|
|
||||||
# res = type(value)
|
|
||||||
# return res.__name__
|
|
||||||
# register.filter('val_type', val_type)
|
|
||||||
#
|
|
||||||
# @register.filter()
|
|
||||||
# def get_cols_table_data_for_row_when_cols3(value, row):
|
|
||||||
# el_count = 3
|
|
||||||
# from_el = (row-1) * el_count
|
|
||||||
# to_el = row * el_count
|
|
||||||
# part = list(value)[from_el:to_el]
|
|
||||||
# return part
|
|
||||||
# # register.filter('val_type', val_type)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# @register.filter
|
|
||||||
# @stringfilter
|
|
||||||
# def correct_for_tables(value):
|
|
||||||
# if value in ['None', '0.0']:
|
|
||||||
# return '-'
|
|
||||||
# return value
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# @register.filter
|
|
||||||
# @stringfilter
|
|
||||||
# def del_bad_symbols(value):
|
|
||||||
# from BaseModels.functions import del_bad_symbols
|
|
||||||
# return del_bad_symbols(value)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# @register.filter
|
|
||||||
# @stringfilter
|
|
||||||
# def del_amp_symbols(value):
|
|
||||||
# from BaseModels.functions import del_nbsp
|
|
||||||
# return del_nbsp(value)
|
|
||||||
#
|
|
||||||
# @register.filter
|
|
||||||
@register.simple_tag()
|
|
||||||
def check_subscribe_option(s_user, option_name):
|
|
||||||
from ..funcs import check_option_in_cur_user_subscribe
|
|
||||||
res = check_option_in_cur_user_subscribe(s_user, option_name)
|
|
||||||
return res
|
|
||||||
#
|
|
||||||
# @register.filter
|
|
||||||
# @stringfilter
|
|
||||||
# def get_color_by_number(value, arg=None):
|
|
||||||
#
|
|
||||||
# color = None
|
|
||||||
# try:
|
|
||||||
# val = float(value)
|
|
||||||
#
|
|
||||||
# if not color and arg == u'%':
|
|
||||||
#
|
|
||||||
# color = u'black'
|
|
||||||
# if val > 50:
|
|
||||||
# color = u'green'
|
|
||||||
# elif val <= 50 and val >= 25:
|
|
||||||
# color = u'#6c8107'
|
|
||||||
# elif val <= 25 and val >= 10:
|
|
||||||
# color = u'#a89803'
|
|
||||||
# elif val <= 10 and val >= 5:
|
|
||||||
# color = u'#e6a707'
|
|
||||||
# elif val <= 5 and val >= 0:
|
|
||||||
# color = u'#e67307'
|
|
||||||
# elif val <= 0:
|
|
||||||
# color = u'red'
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# # val_range = val_max - val_min
|
|
||||||
# # # val_percent = (val_range * 100 / val) - 100
|
|
||||||
# # offset = -(val_min + -(val))
|
|
||||||
# # if val <0:
|
|
||||||
# # val = offset
|
|
||||||
# # if val > val_max:
|
|
||||||
# # val = val_max
|
|
||||||
# # elif val < 0:
|
|
||||||
# # val = 0
|
|
||||||
# #
|
|
||||||
# # color_range = 16711680 - 1211136
|
|
||||||
# # val_1unit = float(color_range) / float(val_range)
|
|
||||||
# # dec_color = 16711680 - int(val_1unit * val)
|
|
||||||
#
|
|
||||||
# if not color:
|
|
||||||
# color = u'black'
|
|
||||||
# if val > 1000:
|
|
||||||
# color = u'green'
|
|
||||||
# elif val <= 1000 and val >= 500:
|
|
||||||
# color = u'#6c8107'
|
|
||||||
# elif val <= 500 and val >= 250:
|
|
||||||
# color = u'#a89803'
|
|
||||||
# elif val <= 250 and val >= 125:
|
|
||||||
# color = u'#e6a707'
|
|
||||||
# elif val <= 125 and val >= 50:
|
|
||||||
# color = u'#e67307'
|
|
||||||
# elif val <= 50:
|
|
||||||
# color = u'red'
|
|
||||||
#
|
|
||||||
# # s = u'style="color: #{0}12;"'.format(str(hex(dec_color))[2:6])
|
|
||||||
# s = u'style="color: {0};"'.format(color)
|
|
||||||
# return s
|
|
||||||
# except:
|
|
||||||
# return u''
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# # @register.filter
|
|
||||||
# # @stringfilter
|
|
||||||
# # def check_aprox_compare_strings(search_phrase, txt):
|
|
||||||
# # from ProductApp.search import get_highlight_string
|
|
||||||
# #
|
|
||||||
# # s = get_highlight_string(search_phrase, txt)
|
|
||||||
# #
|
|
||||||
# # return s
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
9
SubscribesApp/urls.py
Normal file
9
SubscribesApp/urls.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from SubscribesApp.views import SubscribersView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
|
||||||
|
path('auto-subscribe/', SubscribersView.as_view(), name='auto_subscribe'),
|
||||||
|
|
||||||
|
]
|
||||||
@@ -1,3 +1,43 @@
|
|||||||
from django.shortcuts import render
|
from django.contrib.auth.models import User
|
||||||
|
from django.http import JsonResponse
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
# Create your views here.
|
from SubscribesApp.models import SubscribeForUser
|
||||||
|
from SubscribesApp.serializers import SubscribersSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class SubscribersView(APIView):
|
||||||
|
# permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
serializer = SubscribersSerializer(data=request.data)
|
||||||
|
|
||||||
|
if serializer.is_valid():
|
||||||
|
validated_data = serializer.validated_data
|
||||||
|
email = validated_data['email']
|
||||||
|
email_notification = validated_data['email_notification']
|
||||||
|
auto_subscribe = validated_data['auto_subscribe']
|
||||||
|
|
||||||
|
user = User.objects.filter(email=email)
|
||||||
|
|
||||||
|
if user:
|
||||||
|
|
||||||
|
subscribe_for_user = SubscribeForUser.objects.filter(user_id=user[0].id)
|
||||||
|
|
||||||
|
if email_notification:
|
||||||
|
subscribe_for_user.update(receive_finish_subscribe_msg=True)
|
||||||
|
else:
|
||||||
|
subscribe_for_user.update(receive_finish_subscribe_msg=False)
|
||||||
|
|
||||||
|
if auto_subscribe:
|
||||||
|
subscribe_for_user.update(auto_continue=True)
|
||||||
|
else:
|
||||||
|
subscribe_for_user.update(auto_continue=False)
|
||||||
|
|
||||||
|
return JsonResponse({"message": "Subscriptions updated successfully"}, status=status.HTTP_200_OK)
|
||||||
|
else:
|
||||||
|
return JsonResponse({"message": "User not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
else:
|
||||||
|
return JsonResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
27
TWB/celery.py
Executable file
27
TWB/celery.py
Executable file
@@ -0,0 +1,27 @@
|
|||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from celery import Celery
|
||||||
|
from celery.schedules import crontab
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TWB.settings")
|
||||||
|
|
||||||
|
app = Celery('bo', include=['TWB.tasks'])
|
||||||
|
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||||
|
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||||
|
|
||||||
|
app.conf.beat_schedule = {
|
||||||
|
'update-currency-rates': {
|
||||||
|
'task': 'TWB.tasks.check_auto_subscribe',
|
||||||
|
'schedule': crontab(minute=0, hour='*/1'),
|
||||||
|
},
|
||||||
|
'subscription_expiration_check': {
|
||||||
|
'task': 'TWB.tasks.subscription_expiration_check',
|
||||||
|
'schedule': crontab(hour=0, minute=0),
|
||||||
|
# 'schedule': crontab(minute='*', hour='*'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
app.conf.broker_url = settings.CELERY_BROKER_URL
|
||||||
@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.2/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from decouple import config
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
@@ -29,22 +30,13 @@ DEBUG = True
|
|||||||
|
|
||||||
ALLOWED_HOSTS = ["*"]
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
# https://web-push-codelab.glitch.me/
|
|
||||||
WEBPUSH_SETTINGS = {
|
WEBPUSH_SETTINGS = {
|
||||||
"VAPID_PUBLIC_KEY": "BNUNtlKRY-9h2rFemuT6cODbg1Lkl9zMJJl9vcoVxoSXOYTpT-y8iHIseTsrzsSH03462tjYNx38fTkWyumKyEM",
|
"VAPID_PUBLIC_KEY": "BKS8byh3MucwCF2h06JY9oey1s1RYII09j-j3ehI3qTYhs965UHv0qNPl-jFjQBbIJCvjVXm9RW6t_oJJK8yMOk",
|
||||||
"VAPID_PRIVATE_KEY": "ECoHc1i_XcLEo6KmkF76sHvdk49qBA4aNFyns6N3fPs",
|
"VAPID_PRIVATE_KEY": "f5NMgOntBtRqsyeKwEzloK-051ggMnZGF_GFimERY0w",
|
||||||
"VAPID_ADMIN_EMAIL": "tripwithbonus@gmail.com"
|
"VAPID_ADMIN_EMAIL": "admin@tripwb.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
PAY_SYSTEM_URL = 'https://sandboxapi.paymtech.kz/'
|
|
||||||
PKCS12_PASS = 'QNlhRStcY7mB'
|
|
||||||
API_PASS = 'aPqSRVZhxFjjSqbB'
|
|
||||||
PKCS12_FILENAME = 'dvldigitalprojects.p12'
|
|
||||||
|
|
||||||
# PAY_SYSTEM_URL = 'https://api.paymtech.kz/'
|
|
||||||
# PKCS12_PASS = 'fzSBm6WISje7'
|
|
||||||
# API_PASS = 't9g2+bZSvxNxCu+t'
|
|
||||||
# PKCS12_FILENAME = 'dvldigitalprojects_prod.p12'
|
|
||||||
|
|
||||||
SOCIALACCOUNT_LOGIN_ON_GET=True
|
SOCIALACCOUNT_LOGIN_ON_GET=True
|
||||||
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
|
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
|
||||||
@@ -54,9 +46,7 @@ ACCOUNT_USERNAME_REQUIRED = False
|
|||||||
ACCOUNT_AUTHENTICATION_METHOD = 'email'
|
ACCOUNT_AUTHENTICATION_METHOD = 'email'
|
||||||
ACCOUNT_EMAIL_VERIFICATION = 'optional'
|
ACCOUNT_EMAIL_VERIFICATION = 'optional'
|
||||||
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
|
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
|
||||||
# LOGIN_URL = '/profile/login/'
|
LOGIN_URL = '/profile/login/'
|
||||||
from django.urls import reverse_lazy
|
|
||||||
LOGIN_URL = reverse_lazy('login_profile')
|
|
||||||
|
|
||||||
LOGOUT_REDIRECT_URL = '/profile/login/'
|
LOGOUT_REDIRECT_URL = '/profile/login/'
|
||||||
|
|
||||||
@@ -71,7 +61,6 @@ AUTHENTICATION_BACKENDS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SOCIALACCOUNT_PROVIDERS = {
|
SOCIALACCOUNT_PROVIDERS = {
|
||||||
'google': {
|
'google': {
|
||||||
'SCOPE': [
|
'SCOPE': [
|
||||||
@@ -104,8 +93,6 @@ INSTALLED_APPS = [
|
|||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'django.contrib.humanize',
|
'django.contrib.humanize',
|
||||||
|
|
||||||
'django.contrib.sitemaps',
|
|
||||||
|
|
||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
|
|
||||||
'colorfield',
|
'colorfield',
|
||||||
@@ -120,8 +107,6 @@ INSTALLED_APPS = [
|
|||||||
'allauth.socialaccount',
|
'allauth.socialaccount',
|
||||||
'allauth.socialaccount.providers.google',
|
'allauth.socialaccount.providers.google',
|
||||||
|
|
||||||
'rosetta',
|
|
||||||
|
|
||||||
'GeneralApp',
|
'GeneralApp',
|
||||||
'AuthApp',
|
'AuthApp',
|
||||||
'RoutesApp',
|
'RoutesApp',
|
||||||
@@ -129,7 +114,6 @@ INSTALLED_APPS = [
|
|||||||
'ArticlesApp',
|
'ArticlesApp',
|
||||||
'SubscribesApp',
|
'SubscribesApp',
|
||||||
'PushMessages',
|
'PushMessages',
|
||||||
'BillingApp',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@@ -173,8 +157,7 @@ TEMPLATES = [
|
|||||||
# WSGI_APPLICATION = 'TWB.wsgi.application'
|
# WSGI_APPLICATION = 'TWB.wsgi.application'
|
||||||
ASGI_APPLICATION = 'TWB.asgi.application'
|
ASGI_APPLICATION = 'TWB.asgi.application'
|
||||||
|
|
||||||
# WS_ADDRESS = 'localhost:8000'
|
WS_ADDRESS = 'localhost:8000'
|
||||||
WS_ADDRESS = 'tripwb.com'
|
|
||||||
|
|
||||||
CHANNEL_LAYERS = {
|
CHANNEL_LAYERS = {
|
||||||
'default': {
|
'default': {
|
||||||
@@ -189,11 +172,8 @@ CHANNEL_LAYERS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
POSTGRES_DB = config('POSTGRES_DB')
|
||||||
|
POSTGRES_USER = config('POSTGRES_USER')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
@@ -202,8 +182,8 @@ CHANNEL_LAYERS = {
|
|||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||||
'NAME': 'twbDB',
|
'NAME': POSTGRES_DB,
|
||||||
'USER': 'test_user',
|
'USER': POSTGRES_USER,
|
||||||
'PASSWORD': 'test_db_pass',
|
'PASSWORD': 'test_db_pass',
|
||||||
'HOST': '127.0.0.1',
|
'HOST': '127.0.0.1',
|
||||||
'PORT': '5432',
|
'PORT': '5432',
|
||||||
@@ -266,7 +246,6 @@ LOCALE_PATHS = (
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gettext = lambda s: s
|
gettext = lambda s: s
|
||||||
LANGUAGES = (
|
LANGUAGES = (
|
||||||
(u'ru', gettext(u'Russian')),
|
(u'ru', gettext(u'Russian')),
|
||||||
@@ -354,9 +333,15 @@ CKEDITOR_CONFIGS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CELERY_BROKER_URL = config('CELERY_BROKER_URL')
|
||||||
|
CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND')
|
||||||
|
|
||||||
ROSETTA_MESSAGES_PER_PAGE = 100
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
ROSETTA_SHOW_AT_ADMIN_PANEL = True
|
EMAIL_HOST = 'smtp.gmail.com'
|
||||||
|
EMAIL_USE_TLS = True
|
||||||
|
EMAIL_PORT = 587
|
||||||
|
EMAIL_HOST_USER = config('EMAIL_HOST_USER')
|
||||||
|
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD')
|
||||||
|
|
||||||
|
|
||||||
# CKEDITOR_OPTIONS = {
|
# CKEDITOR_OPTIONS = {
|
||||||
|
|||||||
40
TWB/tasks.py
Normal file
40
TWB/tasks.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
|
||||||
|
from SubscribesApp.models import SubscribeForUser
|
||||||
|
from TWB import settings
|
||||||
|
from TWB.celery import app
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def check_auto_subscribe():
|
||||||
|
current_time = datetime.now()
|
||||||
|
subscribes = SubscribeForUser.objects.filter(auto_continue=True)
|
||||||
|
if subscribes:
|
||||||
|
for subscribe in subscribes:
|
||||||
|
if subscribe.paid_period_to_DT and subscribe.paid_period_to_DT <= current_time + timedelta(hours=1):
|
||||||
|
user_email = subscribe.user.email
|
||||||
|
subject = 'Подписка продлена!'
|
||||||
|
message = 'Ваша подписка успешно продлена!'
|
||||||
|
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
|
||||||
|
else:
|
||||||
|
print('Нету подписок')
|
||||||
|
|
||||||
|
|
||||||
|
@app.task
|
||||||
|
def subscription_expiration_check():
|
||||||
|
current_time = datetime.now()
|
||||||
|
subscribes = SubscribeForUser.objects.filter(paid_period_to_DT__gte=current_time)
|
||||||
|
if subscribes:
|
||||||
|
for subscribe in subscribes:
|
||||||
|
expiration_date = subscribe.paid_period_to_DT
|
||||||
|
remaining_days = (expiration_date - current_time).days
|
||||||
|
|
||||||
|
if remaining_days <= 7:
|
||||||
|
message = f'Ваша подписка заканчивается через {remaining_days} дня. Пожалуйста, продлите её.'
|
||||||
|
|
||||||
|
user_email = subscribe.user.email
|
||||||
|
subject = 'Подписка истекает!'
|
||||||
|
send_mail(subject, message, settings.EMAIL_HOST_USER, [user_email], fail_silently=False)
|
||||||
|
else:
|
||||||
|
print('Нету подписок')
|
||||||
13
TWB/urls.py
13
TWB/urls.py
@@ -1,16 +1,13 @@
|
|||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include, re_path
|
from django.urls import path, include
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from GeneralApp.views import Page404
|
from GeneralApp.views import Page404
|
||||||
from AuthApp.views import login_View
|
from AuthApp.views import login_View
|
||||||
from django.views.generic.base import RedirectView
|
|
||||||
|
|
||||||
handler404 = Page404
|
handler404 = Page404
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# path('admin/', admin.site.urls),
|
|
||||||
path('ckeditor/', include('ckeditor_uploader.urls')),
|
path('ckeditor/', include('ckeditor_uploader.urls')),
|
||||||
path('i18n/', include('django.conf.urls.i18n')),
|
path('i18n/', include('django.conf.urls.i18n')),
|
||||||
|
|
||||||
@@ -41,8 +38,8 @@ urlpatterns = [
|
|||||||
path('test_404', Page404, name='page_404'),
|
path('test_404', Page404, name='page_404'),
|
||||||
|
|
||||||
path('', include('PushMessages.urls')),
|
path('', include('PushMessages.urls')),
|
||||||
|
path('', include('SubscribesApp.urls')),
|
||||||
|
|
||||||
path('', include('SitemapApp.urls')),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
from django.conf.urls.i18n import i18n_patterns
|
from django.conf.urls.i18n import i18n_patterns
|
||||||
@@ -57,13 +54,7 @@ urlpatterns += i18n_patterns(
|
|||||||
|
|
||||||
path('', include('ArticlesApp.urls_translate')),
|
path('', include('ArticlesApp.urls_translate')),
|
||||||
|
|
||||||
path('favicon.svg',RedirectView.as_view(url='/static/favicon.ico')),
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'rosetta' in settings.INSTALLED_APPS:
|
|
||||||
urlpatterns += [
|
|
||||||
re_path(r'^rosetta/', include('rosetta.urls'))
|
|
||||||
]
|
|
||||||
|
|
||||||
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
Binary file not shown.
Binary file not shown.
8
env.sample
Normal file
8
env.sample
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
EMAIL_HOST_USER=
|
||||||
|
EMAIL_HOST_PASSWORD=
|
||||||
|
|
||||||
|
POSTGRES_DB=
|
||||||
|
POSTGRES_USER=
|
||||||
|
|
||||||
|
CELERY_BROKER_URL=
|
||||||
|
CELERY_RESULT_BACKEND=
|
||||||
1360
favicon.svg
1360
favicon.svg
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 95 KiB |
@@ -1 +0,0 @@
|
|||||||
google-site-verification: google180852ecd111cd7b.html
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@ Django==4.2.2
|
|||||||
django-ckeditor==6.5.1
|
django-ckeditor==6.5.1
|
||||||
psycopg2-binary==2.9.6
|
psycopg2-binary==2.9.6
|
||||||
requests
|
requests
|
||||||
Pillow==9.5.0
|
|
||||||
django-modeltranslation==0.18.10
|
django-modeltranslation==0.18.10
|
||||||
overpass
|
overpass
|
||||||
geopy
|
geopy
|
||||||
@@ -10,11 +9,9 @@ channels==4.0.0
|
|||||||
daphne==4.0.0
|
daphne==4.0.0
|
||||||
channels-redis==4.1.0
|
channels-redis==4.1.0
|
||||||
django-colorfield
|
django-colorfield
|
||||||
django-webpush==0.3.6
|
django-webpush==0.3.5
|
||||||
django-allauth==0.60.0
|
django-allauth==0.60.0
|
||||||
pytz==2024.1
|
pytz==2024.1
|
||||||
requests-pkcs12==1.24
|
celery==5.3.6
|
||||||
#django-tz-detect==0.4.0
|
djangorestframework==3.14.0
|
||||||
django-rosetta==0.10.0
|
python-decouple==3.8
|
||||||
timezonefinder==6.5.2
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow: /
|
Disallow: /
|
||||||
Disallow: */admin/*
|
|
||||||
|
|
||||||
Host: dev.tripwb.com
|
Host: tripwb.com
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
from BaseModels.admin_utils import (
|
from BaseModels.admin_utils import Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline
|
||||||
Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline,
|
|
||||||
AdminImageWidget, get_image_thumb
|
|
||||||
)
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
|
|
||||||
class Admin_BaseModel(Admin_BaseIconModel):
|
class Admin_BaseModel(Admin_BaseIconModel):
|
||||||
@@ -90,69 +86,24 @@ class AdminTranslationBase(TranslationAdmin):
|
|||||||
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
||||||
}
|
}
|
||||||
|
|
||||||
from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
|
from modeltranslation.admin import TranslationGenericStackedInline
|
||||||
class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
|
class AdminStacked_FAQitem(TranslationGenericStackedInline):
|
||||||
formfield_overrides = {
|
|
||||||
models.ImageField: {'widget': AdminImageWidget},
|
|
||||||
}
|
|
||||||
|
|
||||||
def image_thumb(self, obj):
|
|
||||||
return get_image_thumb(self, obj)
|
|
||||||
|
|
||||||
image_thumb.short_description = _('Миниатюра')
|
|
||||||
image_thumb.allow_tags = True
|
|
||||||
|
|
||||||
class Media:
|
|
||||||
|
|
||||||
js = (
|
|
||||||
'modeltranslation/js/force_jquery.js',
|
|
||||||
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
|
|
||||||
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
|
|
||||||
'modeltranslation/js/tabbed_translation_fields.js',
|
|
||||||
)
|
|
||||||
css = {
|
|
||||||
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
|
||||||
}
|
|
||||||
|
|
||||||
class TranslationGenericStackedInlineCustom(TranslationGenericStackedInline):
|
|
||||||
formfield_overrides = {
|
|
||||||
models.ImageField: {'widget': AdminImageWidget},
|
|
||||||
}
|
|
||||||
|
|
||||||
def image_thumb(self, obj):
|
|
||||||
return get_image_thumb(self, obj)
|
|
||||||
|
|
||||||
image_thumb.short_description = _('Миниатюра')
|
|
||||||
image_thumb.allow_tags = True
|
|
||||||
|
|
||||||
class Media:
|
|
||||||
|
|
||||||
js = (
|
|
||||||
'modeltranslation/js/force_jquery.js',
|
|
||||||
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
|
|
||||||
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
|
|
||||||
'modeltranslation/js/tabbed_translation_fields.js',
|
|
||||||
)
|
|
||||||
css = {
|
|
||||||
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AdminStacked_FAQitem(TranslationGenericStackedInlineCustom):
|
|
||||||
from GeneralApp.models import FAQitem
|
from GeneralApp.models import FAQitem
|
||||||
model = FAQitem
|
model = FAQitem
|
||||||
extra = 0
|
extra = 0
|
||||||
fields = ['order', 'question', 'answer']
|
fields = ['order', 'question', 'answer']
|
||||||
|
|
||||||
|
class Media:
|
||||||
|
|
||||||
|
js = (
|
||||||
class AdminTabular_Mediaitem(TranslationGenericTabularInlineCustom):
|
'modeltranslation/js/force_jquery.js',
|
||||||
from GeneralApp.models import MediaItem
|
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
|
||||||
model = MediaItem
|
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js',
|
||||||
extra = 0
|
'modeltranslation/js/tabbed_translation_fields.js',
|
||||||
fields = ['order', 'video', 'picture']
|
)
|
||||||
|
css = {
|
||||||
|
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
||||||
|
}
|
||||||
|
|
||||||
class Admin_BaseModelViewPage(Admin_BaseIconModel):
|
class Admin_BaseModelViewPage(Admin_BaseIconModel):
|
||||||
pass
|
pass
|
||||||
@@ -178,7 +129,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
|
|||||||
# else:
|
# else:
|
||||||
# return {}
|
# return {}
|
||||||
#
|
#
|
||||||
inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]
|
inlines = [AdminStacked_FAQitem]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
@media (max-width: 1280px){
|
@media (max-width: 1280px){
|
||||||
|
|
||||||
.remove_route{
|
.remove_route{
|
||||||
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +116,11 @@
|
|||||||
}
|
}
|
||||||
@media (max-width: 1180px){
|
@media (max-width: 1180px){
|
||||||
|
|
||||||
.container_inf_about_moving{
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input_list.find_route{
|
.input_list.find_route{
|
||||||
left: unset;
|
left: unset;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown{
|
|
||||||
vertical-align: sub;
|
|
||||||
}
|
|
||||||
|
|
||||||
.handler_curtain_left{
|
.handler_curtain_left{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -144,10 +136,6 @@
|
|||||||
transition: 200ms;
|
transition: 200ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unsubscribe_info {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container_content_handler_curtain_left{
|
.container_content_handler_curtain_left{
|
||||||
display: flex;
|
display: flex;
|
||||||
rotate: 90deg;
|
rotate: 90deg;
|
||||||
@@ -266,7 +254,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
header{
|
header{
|
||||||
padding: 3px 16px;
|
padding: 5px 16px;
|
||||||
margin-top: unset;
|
margin-top: unset;
|
||||||
}
|
}
|
||||||
.header_logo, .header_btn_mover, .header_btn_sender{
|
.header_logo, .header_btn_mover, .header_btn_sender{
|
||||||
@@ -371,7 +359,7 @@
|
|||||||
|
|
||||||
|
|
||||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
||||||
width: 98%;
|
width: 100%;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,14 +386,11 @@
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
.header_logo_mobile {
|
.header_logo_mobile {
|
||||||
margin-right: 20px;
|
margin-right: 37px;
|
||||||
}
|
}
|
||||||
.line_f_header{
|
.line_f_header{
|
||||||
top: 43px;
|
top: 43px;
|
||||||
}
|
}
|
||||||
header .header-second{
|
|
||||||
margin-top: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.self_news_img{
|
.self_news_img{
|
||||||
width: 40%;
|
width: 40%;
|
||||||
@@ -509,9 +494,7 @@
|
|||||||
|
|
||||||
.footer_logo{
|
.footer_logo{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 40px auto;
|
margin: 40px 0;
|
||||||
max-width: 90px;
|
|
||||||
/*margin-left: 43%;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer_text_sub{
|
.footer_text_sub{
|
||||||
@@ -734,7 +717,7 @@
|
|||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ч
|
|
||||||
.arrange_subscribe{
|
.arrange_subscribe{
|
||||||
margin: 20px auto 20px auto;
|
margin: 20px auto 20px auto;
|
||||||
}
|
}
|
||||||
@@ -1118,12 +1101,9 @@
|
|||||||
.left-part-carrier-card, .inf_carrier_container{
|
.left-part-carrier-card, .inf_carrier_container{
|
||||||
width: unset;
|
width: unset;
|
||||||
float: none;
|
float: none;
|
||||||
padding: 1px 20px;
|
padding: 1px 15px;
|
||||||
border-right: unset;
|
border-right: unset;
|
||||||
}
|
}
|
||||||
.control_frame{
|
|
||||||
top: 3px;
|
|
||||||
}
|
|
||||||
.inf_carrier_container{
|
.inf_carrier_container{
|
||||||
padding-top: 70px;
|
padding-top: 70px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
@@ -1153,7 +1133,7 @@
|
|||||||
.cargo_type_trans{
|
.cargo_type_trans{
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
float: unset;
|
/*float: unset;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.from-to-country-container-carrier{
|
.from-to-country-container-carrier{
|
||||||
@@ -1201,7 +1181,7 @@
|
|||||||
.from-to-city-text{
|
.from-to-city-text{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
/*padding-bottom: 10px;*/
|
padding-bottom: 10px;
|
||||||
/*padding-top: unset;*/
|
/*padding-top: unset;*/
|
||||||
}
|
}
|
||||||
.arrow_inf_about_moving{
|
.arrow_inf_about_moving{
|
||||||
@@ -1214,7 +1194,6 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 7px;
|
|
||||||
}
|
}
|
||||||
.inf_carrier_icon{
|
.inf_carrier_icon{
|
||||||
width: 20px;
|
width: 20px;
|
||||||
@@ -1229,7 +1208,7 @@
|
|||||||
padding-right: unset;
|
padding-right: unset;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
top: unset;
|
top: unset;
|
||||||
/*background: linear-gradient(99deg, #000000 1%, #ffffff 16%, #ffffff);*/
|
background: linear-gradient(99deg, #000000 1%, #ffffff 16%, #ffffff);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
@@ -1239,7 +1218,6 @@
|
|||||||
|
|
||||||
.name_carrier{
|
.name_carrier{
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
position: unset;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1345,10 +1323,6 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
}
|
}
|
||||||
.subscribe_wrpapper{
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_another_subscribe{
|
.text_another_subscribe{
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -1510,19 +1484,11 @@
|
|||||||
width: 153px;
|
width: 153px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup_content{
|
|
||||||
width: 41%;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 950px){
|
@media (max-width: 950px){
|
||||||
|
|
||||||
|
|
||||||
#title_static_small{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info_profile{
|
.info_profile{
|
||||||
width: 65%;
|
width: 65%;
|
||||||
float: none;
|
float: none;
|
||||||
@@ -1558,9 +1524,6 @@
|
|||||||
.pag_news_item_text{
|
.pag_news_item_text{
|
||||||
width: unset;
|
width: unset;
|
||||||
}
|
}
|
||||||
.popup_content{
|
|
||||||
width: 52%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@media (max-width: 850px){
|
@media (max-width: 850px){
|
||||||
|
|
||||||
@@ -1605,7 +1568,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.read_more_about_subscribe, .read_more_about_subscribe.error {
|
.read_more_about_subscribe{
|
||||||
padding: 0 14px;
|
padding: 0 14px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -1664,21 +1627,15 @@
|
|||||||
|
|
||||||
.toggle_switch_cont{
|
.toggle_switch_cont{
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
width: unset;
|
width: 12%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
|
|
||||||
|
|
||||||
.line_inf_about_moving{
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
.marker_messages_mobile{
|
.marker_messages_mobile{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -1694,9 +1651,6 @@
|
|||||||
.marker_messages_mobile.show{
|
.marker_messages_mobile.show{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.popup_content>.confirm_profile_btn{
|
|
||||||
width: 90%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 828px){
|
@media (max-width: 828px){
|
||||||
@@ -1730,9 +1684,8 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.another_subscribe {
|
||||||
.subscribe_wrpapper{
|
flex-direction: column;
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving>.line_inf_about_moving>.carrier_inf_moving.left{
|
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving>.line_inf_about_moving>.carrier_inf_moving.left{
|
||||||
@@ -1788,10 +1741,6 @@
|
|||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content-lang{
|
|
||||||
z-index: 1 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu_buttons.right.open .handler_menu{
|
.menu_buttons.right.open .handler_menu{
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@@ -1843,20 +1792,14 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.another_subscribe{
|
||||||
.subscribe_wrpapper{
|
padding: 10px;
|
||||||
padding: 10px;
|
|
||||||
flex-direction: unset;
|
flex-direction: unset;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.inf_carrier_icon{
|
.inf_carrier_icon{
|
||||||
/*width: 3%;*/
|
/*width: 3%;*/
|
||||||
}
|
}
|
||||||
.popup_content{
|
|
||||||
width: 70%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@media (max-width: 687px){
|
@media (max-width: 687px){
|
||||||
/*.to_address_point_txt.find_route {*/
|
/*.to_address_point_txt.find_route {*/
|
||||||
@@ -1865,10 +1808,6 @@
|
|||||||
/*.from_address_point_txt.find_route.first {*/
|
/*.from_address_point_txt.find_route.first {*/
|
||||||
/* width: 52.1%;*/
|
/* width: 52.1%;*/
|
||||||
/*}*/
|
/*}*/
|
||||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
|
||||||
width: 98%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.container_inf_about_moving {
|
.container_inf_about_moving {
|
||||||
width: 97%;
|
width: 97%;
|
||||||
@@ -1909,10 +1848,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
|
||||||
width: 89%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.phones_carrier{
|
.phones_carrier{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -1938,7 +1873,6 @@
|
|||||||
|
|
||||||
.container_inf_about_moving{
|
.container_inf_about_moving{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow_inf_about_moving{
|
.arrow_inf_about_moving{
|
||||||
@@ -1959,11 +1893,6 @@
|
|||||||
margin-bottom: unset;
|
margin-bottom: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name_carrier{
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.splitter-from-to-country{
|
.splitter-from-to-country{
|
||||||
@@ -2040,7 +1969,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-content{
|
.dropdown-content{
|
||||||
width: 202px;
|
width: 190px;
|
||||||
top: 27px;
|
top: 27px;
|
||||||
left: -83px;
|
left: -83px;
|
||||||
}
|
}
|
||||||
@@ -2095,13 +2024,9 @@
|
|||||||
|
|
||||||
.another_subscribe{
|
.another_subscribe{
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: unset;
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
.subscribe_wrpapper, .error_order{
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: unset;
|
|
||||||
width: unset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,178 +0,0 @@
|
|||||||
.about {
|
|
||||||
margin-bottom: 168px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about {
|
|
||||||
margin-bottom: 188px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1304.98px) {
|
|
||||||
.about {
|
|
||||||
margin-bottom: 138px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about {
|
|
||||||
margin-bottom: 110px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about .title {
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about .title {
|
|
||||||
margin-bottom: 49px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1304.98px) {
|
|
||||||
.about .title {
|
|
||||||
margin-bottom: 39px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about .title {
|
|
||||||
margin-bottom: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 479.98px) {
|
|
||||||
.about .title {
|
|
||||||
margin-bottom: 37px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about__grid {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__img {
|
|
||||||
box-shadow: inset 18.19px 1.21px 18.19px 0 #FFFFFFCC, inset -18.19px -1.21px 18.19px 0 #4052801A, 48.5px 36.38px 36.38px 0 #6B7F9933;
|
|
||||||
border-radius: 31px;
|
|
||||||
margin-left: -20px;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about__img {
|
|
||||||
margin-top: 19px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1304.98px) {
|
|
||||||
.about__img {
|
|
||||||
margin-left: -10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about__img {
|
|
||||||
margin-left: 0;
|
|
||||||
margin-bottom: 49px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 479.98px) {
|
|
||||||
.about__img {
|
|
||||||
margin-bottom: 38px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__right {
|
|
||||||
text-align: left;
|
|
||||||
padding-top: 43px;
|
|
||||||
padding-left: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about__right {
|
|
||||||
padding-top: 90px;
|
|
||||||
padding-left: 21px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1304.98px) {
|
|
||||||
.about__right {
|
|
||||||
padding-left: 11px;
|
|
||||||
padding-top: 19px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about__right {
|
|
||||||
padding: 0 8px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 479.98px) {
|
|
||||||
.about__right {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__right::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__half {
|
|
||||||
max-width: 50%;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about__half {
|
|
||||||
max-width: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about__half:last-child {
|
|
||||||
padding-left: 16px;
|
|
||||||
max-width: 47%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 991.98px) {
|
|
||||||
.about__half:last-child {
|
|
||||||
max-width: initial;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.about b {
|
|
||||||
letter-spacing: 0.4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about b {
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 479.98px) {
|
|
||||||
.about b {
|
|
||||||
letter-spacing: 0.9px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1720px) {
|
|
||||||
.about p {
|
|
||||||
margin-bottom: 39px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
static/css/moover/animate.css
vendored
1
static/css/moover/animate.css
vendored
@@ -1 +0,0 @@
|
|||||||
.animate{padding:60px 40px 49px;opacity:0;background-color:var(--color-black2);border-radius:30px;color:white;margin-bottom:160px}@media (min-width: 1720px){.animate{padding-top:100px;padding-bottom:89px;margin-bottom:180px}}@media (max-width: 1304.98px){.animate{margin-bottom:141px}}@media (max-width: 991.98px){.animate{padding-top:40px;padding-bottom:29px;margin-bottom:121px}}@media (max-width: 479.98px){.animate{padding:30px 7px 19px}}.animate.left{transform:scale(0);opacity:0}.animate.right{opacity:0;transform:scale(0)}.animate.right .title{margin-bottom:17px}@media (min-width: 1720px){.animate.right .title{max-width:80%;margin-bottom:40px}}@media (max-width: 1304.98px){.animate.right .title{margin-bottom:25px}}@media (max-width: 991.98px){.animate.right .title{margin-bottom:31px}}@media (max-width: 479.98px){.animate.right .title{margin-bottom:20px}}@media (max-width: 991.98px){.animate.right .subtitle{margin-bottom:31px}}@media (max-width: 479.98px){.animate.right .use__btn{margin-top:-11px}}.animate__link{color:var(--color-orange);text-decoration:underline !important}.animate .title{margin-bottom:25px;max-width:87%}@media (min-width: 1720px){.animate .title{margin-bottom:40px}}@media (max-width: 1304.98px){.animate .title{max-width:99%}}@media (max-width: 991.98px){.animate .title{max-width:85%;font-size:24px;line-height:29.05px}}@media (max-width: 767.98px){.animate .title{max-width:100%;margin-bottom:14px}}.animate .subtitle{width:47%;margin:0 auto 23px}@media (min-width: 1720px){.animate .subtitle{line-height:26px;letter-spacing:0.1px;margin-bottom:40px}}@media (max-width: 1304.98px){.animate .subtitle{width:54%}}@media (max-width: 991.98px){.animate .subtitle{width:102%;margin-bottom:26px}}@media (max-width: 479.98px){.animate .use__btn{margin-top:-6px;padding-left:15px;padding-right:15px;display:flex}}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user