Compare commits
5 Commits
9cf25e37ed
...
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
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# packages for node
|
||||
package.json
|
||||
package-lock.json
|
||||
celerybeat-schedule.db
|
||||
|
||||
|
||||
@@ -21,9 +21,6 @@ def get_articles_block_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = request.POST.dict()
|
||||
@@ -45,9 +42,6 @@ def get_articles_block_ajax(request):
|
||||
# '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)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -6,7 +6,7 @@ from datetime import datetime, date
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.template import loader
|
||||
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.contrib.auth.decorators import login_required
|
||||
@@ -85,14 +85,14 @@ def ArticlesPageView(request, year=None):
|
||||
Dict = get_articles(art_kwargs=kwargs)
|
||||
Dict.update({
|
||||
'page': {
|
||||
'title': _('Новости сервиса доставки посылок | TripWB'),
|
||||
'description': _('Обновления, полезные статьи и свежие новости от TripWB ✓ Актуальные новости в мире доставок по всему СНГ ➡️ Следите за нашими новостями'),
|
||||
'title': _('Страница списка новостей'),
|
||||
'description': _('Все новости сайта tripwb.com'),
|
||||
'keywords': _('Все новости сайта tripwb.com'),
|
||||
}
|
||||
})
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ def UserPageView(request, page_url):
|
||||
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -155,5 +155,5 @@ def ArticlesOnePageView(request, art_url):
|
||||
|
||||
|
||||
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))
|
||||
|
||||
@@ -97,14 +97,12 @@ class Admin_User(UserAdmin):
|
||||
save_on_top = True
|
||||
|
||||
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_display_links = ['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', 'date_joined', 'last_login']
|
||||
list_filter = ['user_profile__mailing_on', 'is_staff', 'is_active']
|
||||
|
||||
inlines = (Admin_ProfileInline,)
|
||||
# actions = ['del_all_temp_users', ]
|
||||
|
||||
@@ -26,7 +26,7 @@ class RegistrationForm(forms.Form):
|
||||
email = forms.EmailField()
|
||||
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)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
from django.http import QueryDict
|
||||
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):
|
||||
@@ -32,12 +30,10 @@ def get_profile_page_content_html(request, page_name, data):
|
||||
if page_name == 'chat':
|
||||
from ChatServiceApp.funcs import get_chat_page_content_html
|
||||
return get_chat_page_content_html(request, data)
|
||||
elif (page_name == 'create_route_for_customer' and
|
||||
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
|
||||
elif page_name == 'create_route_for_customer':
|
||||
from RoutesApp.funcs import get_profile_new_route_page_html
|
||||
return get_profile_new_route_page_html(request, {'owner_type': 'customer'})
|
||||
elif (page_name == 'create_route_for_mover' and
|
||||
check_option_in_cur_user_subscribe(request.user, 'размещение заявок')):
|
||||
elif page_name == 'create_route_for_mover':
|
||||
from RoutesApp.funcs import get_profile_new_route_page_html
|
||||
return get_profile_new_route_page_html(request, {'owner_type': 'mover'})
|
||||
elif page_name == 'my_routes':
|
||||
@@ -46,9 +42,8 @@ def get_profile_page_content_html(request, page_name, data):
|
||||
elif page_name == 'support':
|
||||
return get_profile_support_page_content_html(request, data)
|
||||
elif page_name == 'my_subscribe':
|
||||
from SubscribesApp.funcs import get_profile_subscribe_page_content_Dict
|
||||
res = get_profile_subscribe_page_content_Dict(request, check_orders_required=True)
|
||||
return res['html']
|
||||
from SubscribesApp.funcs import get_profile_subscribe_page_content_html
|
||||
return get_profile_subscribe_page_content_html(request)
|
||||
elif page_name == 'change_profile':
|
||||
return get_profile_change_page_content_html(request)
|
||||
elif page_name == 'dashboard':
|
||||
@@ -57,7 +52,7 @@ def get_profile_page_content_html(request, page_name, data):
|
||||
return None
|
||||
|
||||
|
||||
def get_profile_change_page_content_html(request, data=None):
|
||||
def get_profile_change_page_content_html(request):
|
||||
|
||||
init_Dict = {
|
||||
'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,
|
||||
'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
|
||||
form = RegistrationForm(initial=init_Dict)
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ urlpatterns = [
|
||||
|
||||
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_confirm/', change_profile_confirm_ajax, name='change_profile_confirm_ajax'),
|
||||
|
||||
@@ -18,9 +18,9 @@ from django.core.files import File
|
||||
import base64
|
||||
from django.core.validators import validate_email
|
||||
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):
|
||||
# if request.method != 'POST':
|
||||
# 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)
|
||||
# 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):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
email = request.POST['email']
|
||||
@@ -166,13 +45,11 @@ def mailing_subscribe_ajax(request):
|
||||
user.user_profile.mailing_on = True
|
||||
user.user_profile.save(update_fields=['mailing_on'])
|
||||
|
||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
||||
res_Dict = {
|
||||
return JsonResponse({
|
||||
'status': 'sended',
|
||||
'del_form': True,
|
||||
'html': _('Подписка на рассылку для адреса ') + user.email + _(' одобрена')
|
||||
}
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
})
|
||||
|
||||
if not user:
|
||||
try:
|
||||
@@ -185,14 +62,11 @@ def mailing_subscribe_ajax(request):
|
||||
else:
|
||||
redirect_url = f"{reverse('registration_page')}?mailingSubscribeRequired=true"
|
||||
|
||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
||||
res_Dict = {
|
||||
return JsonResponse({
|
||||
'status': 'sended',
|
||||
'redirect_url': redirect_url,
|
||||
'email': email
|
||||
}
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
return JsonResponse(res_Dict)
|
||||
})
|
||||
|
||||
|
||||
except Exception as e:
|
||||
@@ -203,13 +77,9 @@ def mailing_subscribe_ajax(request):
|
||||
|
||||
|
||||
def send_message_ajax(request):
|
||||
print('send_message_ajax')
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = request.POST
|
||||
@@ -313,25 +183,10 @@ def send_message_ajax(request):
|
||||
f'</p>'
|
||||
}
|
||||
|
||||
print('render html for mail')
|
||||
|
||||
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()
|
||||
opts = get_options_by_opt_types('support_email', only_vals=True)
|
||||
print(f'options: {str(opts)}')
|
||||
if opts and 'support_email' in opts:
|
||||
to = [opts['support_email']]
|
||||
else:
|
||||
to = [mail_sets['sender_email']]
|
||||
print(f'to: {str(to)}')
|
||||
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']
|
||||
to = [mail_sets['sender_email'], 'web@syncsystems.net']
|
||||
res = admin_send_mail_by_SMTPlib(
|
||||
mail_sets,
|
||||
subject=subject,
|
||||
@@ -341,14 +196,10 @@ def send_message_ajax(request):
|
||||
|
||||
html = render_to_string('widgets/w_msg_send_success.html', Dict, request)
|
||||
|
||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
||||
res_Dict = {
|
||||
return JsonResponse({
|
||||
'status': 'sended',
|
||||
'html': html
|
||||
}
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
return JsonResponse(res_Dict)
|
||||
|
||||
})
|
||||
except Exception as e:
|
||||
return JsonResponse({
|
||||
'status': 'error',
|
||||
@@ -356,13 +207,11 @@ def send_message_ajax(request):
|
||||
}, status=400)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def chats_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
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)
|
||||
@@ -386,28 +235,19 @@ def chats_ajax(request):
|
||||
Dict.update(get_user_timezone_Dict(request.user, 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
|
||||
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 support_tickets_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
html = get_profile_support_page_content_html(request)
|
||||
|
||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
||||
res_Dict = {'html': html}
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
return JsonResponse(res_Dict)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def change_avatar_confirm_ajax(request):
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.exceptions import RequestDataTooBig
|
||||
@@ -415,8 +255,6 @@ def change_avatar_confirm_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
file_data = json.loads(request.body)
|
||||
@@ -435,19 +273,14 @@ def change_avatar_confirm_ajax(request):
|
||||
print(msg)
|
||||
return JsonResponse({'error': msg}, status=400)
|
||||
|
||||
res_Dict = {'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)
|
||||
return JsonResponse({'url': request.user.user_profile.avatar.url})
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def change_profile_confirm_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
data = request.POST
|
||||
if not data:
|
||||
data = json.loads(request.body)
|
||||
@@ -512,20 +345,15 @@ def change_profile_confirm_ajax(request):
|
||||
if data_for_save:
|
||||
user_profiles.update(**data_for_save)
|
||||
|
||||
html = get_profile_change_page_content_html(request, data)
|
||||
from GeneralApp.funcs import get_add_to_ajax_response_Dict
|
||||
res_Dict = {'html': html}
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
return JsonResponse(res_Dict)
|
||||
html = get_profile_change_page_content_html(request)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def dashboard_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
from .funcs import get_dashboard_page_content_html
|
||||
@@ -539,32 +367,26 @@ def dashboard_ajax(request):
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def change_profile_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
html = get_profile_change_page_content_html(request)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def my_routes_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
Dict = {
|
||||
}
|
||||
|
||||
html = render_to_string('blocks/profile/b_my_routes.html', Dict, request=request)
|
||||
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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
|
||||
@@ -574,8 +396,6 @@ def login_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = request.POST
|
||||
@@ -604,16 +424,11 @@ def login_ajax(request):
|
||||
html = render_to_string('forms/f_login.html', Dict, request=request)
|
||||
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 = {
|
||||
'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)
|
||||
|
||||
except Exception as e:
|
||||
@@ -629,59 +444,45 @@ def login_ajax(request):
|
||||
|
||||
|
||||
|
||||
def send_check_email_after_registration(data_Dict, user):
|
||||
|
||||
def send_registration_mail(data_Dict, 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 - Подтверждение регистрации ')
|
||||
subject = _('Добро пожаловать в Trip With Bonus!')
|
||||
|
||||
Dict = {
|
||||
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
|
||||
'project_name': sets['project_name'],
|
||||
'domain': sets['domain'],
|
||||
'message_title': subject,
|
||||
}
|
||||
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
|
||||
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(
|
||||
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 registration_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = request.POST
|
||||
@@ -702,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 = auth.authenticate(username=new_user_Dict['name'], password=new_user_Dict['pass'])
|
||||
# if user:
|
||||
# auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
||||
if user:
|
||||
auth.login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
||||
|
||||
if 'mailingSubscribeRequired' in data and data['mailingSubscribeRequired'] == 'true':
|
||||
user.user_profile.mailing_on = True
|
||||
|
||||
user.last_name = form.data['lastname']
|
||||
user.first_name = form.data['firstname']
|
||||
user.is_active = False
|
||||
user.save()
|
||||
user.user_profile.phone = form.data['tel']
|
||||
user.user_profile.authMailCode = uuid1().hex
|
||||
user.user_profile.save()
|
||||
|
||||
mail_Dict = {
|
||||
'user': user,
|
||||
'pass': form.data['password']
|
||||
}
|
||||
|
||||
res = send_check_email_after_registration(mail_Dict, user)
|
||||
print(str(res))
|
||||
# res = send_registration_mail(mail_Dict, user)
|
||||
res = send_registration_mail(mail_Dict, user)
|
||||
|
||||
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)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -16,6 +16,7 @@ from datetime import datetime
|
||||
def user_name_str(self):
|
||||
return f'{self.last_name} {self.first_name}'
|
||||
|
||||
|
||||
User.add_to_class("__str__", user_name_str)
|
||||
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ from django.contrib.auth import views
|
||||
urlpatterns = [
|
||||
|
||||
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('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'),
|
||||
@@ -49,9 +46,9 @@ urlpatterns = [
|
||||
#
|
||||
# # -----------------------
|
||||
#
|
||||
path('check_user_registration_and_activate/<int:user_id>/<str:authMailCode>/',
|
||||
check_user_registration_and_activate,
|
||||
name='check_user_registration_and_activate'),
|
||||
# url(r'^check_user_registration_and_activate/(?P<user_id>[\d+]*)/(?P<authCode>[0-9a-z\+\-\_]+)$',
|
||||
# check_user_registration_and_activate,
|
||||
# name='check_user_registration_and_activate'),
|
||||
#
|
||||
# # url(r'^user/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 AuthApp.models import *
|
||||
from django.contrib import auth
|
||||
from django.urls import reverse
|
||||
from django.http import HttpResponse, Http404, HttpResponseRedirect
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.template import loader, RequestContext
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from BaseModels.mailSender import techSendMail
|
||||
@@ -14,68 +13,7 @@ from django.utils.translation import gettext as _
|
||||
from datetime import datetime
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from .funcs import *
|
||||
from GeneralApp.funcs import get_inter_http_response
|
||||
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
|
||||
|
||||
from GeneralApp.funcs import get_inter_http_respose
|
||||
|
||||
def registration_View(request):
|
||||
|
||||
@@ -87,7 +25,7 @@ def registration_View(request):
|
||||
# if request.p
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -103,17 +41,10 @@ def registration_View(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):
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
page_html = get_profile_page_content_html(request, page_name, id)
|
||||
if not page_html:
|
||||
raise Http404
|
||||
|
||||
Dict = {
|
||||
'page_html': page_html,
|
||||
'page_html': get_profile_page_content_html(request, page_name, id),
|
||||
'page_name': page_name,
|
||||
'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'])
|
||||
del request.session['mailingSubscribeRequired']
|
||||
|
||||
# title = _('Личный кабинет пользователя') + ' ' + request.user.first_name + ' ' + request.user.last_name
|
||||
#
|
||||
# Dict.update({
|
||||
# 'page': {
|
||||
# 'title': title,
|
||||
# 'description': title,
|
||||
# 'keywords': title,
|
||||
# }
|
||||
# })
|
||||
title = f"{_('Личный кабинет пользователя')} {request.user.first_name} {request.user.last_name}"
|
||||
|
||||
Dict.update({
|
||||
'page': {
|
||||
'title': title,
|
||||
'description': title,
|
||||
'keywords': title,
|
||||
}
|
||||
})
|
||||
|
||||
# if request.GET and 'mobile' in request.GET and request.GET['mobile'] == 'true':
|
||||
# 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')
|
||||
return get_inter_http_response(t, Dict, request)
|
||||
return get_inter_http_respose(t, 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):
|
||||
# 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')
|
||||
# return HttpResponse(t.render(Dict, request))
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def user_profile_View(request):
|
||||
|
||||
Dict = {}
|
||||
@@ -181,7 +112,7 @@ def user_profile_View(request):
|
||||
# request.COOKIES['user_id'] = request.user.id
|
||||
|
||||
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.set_cookie('user_id', request.user.id)
|
||||
return response
|
||||
@@ -206,7 +137,7 @@ def login_View(request):
|
||||
request.session['mailingSubscribeRequired'] = 'true'
|
||||
|
||||
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))
|
||||
|
||||
|
||||
@@ -278,19 +209,12 @@ def decode_get_param(data):
|
||||
|
||||
|
||||
|
||||
def recovery_password_page_View(request, user_id, token):
|
||||
try:
|
||||
user = User.objects.get(id=user_id, user_profile__authMailCode=token)
|
||||
except User.DoesNotExist:
|
||||
raise Http404
|
||||
def recovery_password_user(request, uidb64=None, token=None):
|
||||
from django.contrib.auth.views import PasswordResetConfirmView
|
||||
|
||||
Dict = {
|
||||
'user': user
|
||||
}
|
||||
return PasswordResetConfirmView(request=request, uidb64=uidb64, token=token
|
||||
)
|
||||
|
||||
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"])
|
||||
|
||||
class BaseModel(models.Model):
|
||||
name = models.TextField(verbose_name=_("Название"),
|
||||
name = models.TextField(verbose_name=_('Название'),
|
||||
help_text=_('Название'), null=True, blank=True)
|
||||
name_plural = models.TextField(verbose_name=_('Название (множественное число)'),
|
||||
null=True, blank=True)
|
||||
@@ -29,31 +29,12 @@ class BaseModel(models.Model):
|
||||
|
||||
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):
|
||||
if self.name:
|
||||
return self.name
|
||||
else:
|
||||
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):
|
||||
if not self.json_data or not node_name in self.json_data:
|
||||
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_items = GenericRelation('GeneralApp.FAQitem', related_query_name='grel_%(class)s_for_faq_item')
|
||||
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
@@ -105,7 +105,6 @@ def admin_send_mail_by_SMTPlib(sets, subject, from_email, to, html_content, atta
|
||||
|
||||
def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_server, smtp_port, smtp_login, smtp_password,
|
||||
attachments=None):
|
||||
print('send_mail_by_SMTPlib')
|
||||
to = to_init
|
||||
# if not settings.prod_server:
|
||||
# to = 'web@syncsystems.net'
|
||||
@@ -124,11 +123,7 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
|
||||
try:
|
||||
# context = ssl.create_default_context()
|
||||
|
||||
print(f'connect to mail server smtp_server={str(smtp_server)} smtp_port={str(smtp_port)}')
|
||||
|
||||
mail_lib = smtplib.SMTP(smtp_server, smtp_port, timeout=60)
|
||||
|
||||
print('connection established')
|
||||
mail_lib = smtplib.SMTP(smtp_server, smtp_port)
|
||||
|
||||
res = mail_lib.ehlo()
|
||||
|
||||
@@ -144,18 +139,14 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
|
||||
res = mail_lib.esmtp_features['auth'] = 'LOGIN PLAIN'
|
||||
# print('mail_lib.esmtp_features = {0}'.format(str(res)))
|
||||
|
||||
print('try to login')
|
||||
|
||||
res = mail_lib.login(smtp_login, smtp_password)
|
||||
# print('mail_lib.login = {0}'.format(str(res)))
|
||||
|
||||
print('login')
|
||||
|
||||
res = None
|
||||
|
||||
if type(to) in (list, tuple):
|
||||
# if sets['sender_email'] in to:
|
||||
# to.remove(sets['sender_email'])
|
||||
if sets['sender_email'] in to:
|
||||
to.remove(sets['sender_email'])
|
||||
|
||||
if len(to) > 1:
|
||||
to_str = u', '.join(to)
|
||||
@@ -168,8 +159,6 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
|
||||
to = []
|
||||
to.append(to_str)
|
||||
|
||||
print(f'send mail to {str(to)}')
|
||||
|
||||
if type(subject) != str:
|
||||
try:
|
||||
subject = subject.decode('utf-8')
|
||||
@@ -179,8 +168,6 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
|
||||
except:
|
||||
pass
|
||||
|
||||
print(f'add context')
|
||||
|
||||
msg = MIMEMultipart()
|
||||
from email.headerregistry import Address
|
||||
msg['From'] = from_email
|
||||
@@ -205,17 +192,13 @@ def send_mail_by_SMTPlib(sets, subject, from_email, to_init, html_content, smtp_
|
||||
res = msg.attach(attachments)
|
||||
# print('else attach file complete = {0}'.format(str(res)))
|
||||
|
||||
print(f'send mail')
|
||||
|
||||
res = mail_lib.sendmail(from_email, to, msg.as_string())
|
||||
|
||||
msg = mail_lib.quit()
|
||||
# print('mail_lib.quit = {0}'.format(str(msg)))
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
msg = (f'send_mail_by_SMTPlib error = {str(e)}\n<br>'
|
||||
f'{str(traceback.format_exc())}')
|
||||
msg = 'send_mail_by_SMTPlib error = {0}'.format(str(e))
|
||||
print(msg)
|
||||
try:
|
||||
mail_lib.quit()
|
||||
|
||||
@@ -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):
|
||||
if not user or not user.is_authenticated:
|
||||
return 0
|
||||
|
||||
msgs = Message.objects.filter(receiver=user, status='sended', group=None)
|
||||
return msgs.count()
|
||||
|
||||
|
||||
@@ -18,15 +18,12 @@ from channels.layers import get_channel_layer
|
||||
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):
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
@@ -38,9 +35,7 @@ def get_file_from_msg_ajax(request):
|
||||
res_Dict = file
|
||||
break
|
||||
|
||||
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, status=200)
|
||||
|
||||
except Exception as 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):
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
@@ -65,12 +57,10 @@ def show_chat_w_user_ajax(request):
|
||||
|
||||
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
|
||||
res_Dict.update(get_add_to_ajax_response_Dict(request.user))
|
||||
return JsonResponse(res_Dict)
|
||||
|
||||
html = render_to_string(tpl_name, Dict, request=request)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
except Exception as e:
|
||||
msg = f'show_chat_w_user_ajax Error = {str(e)}'
|
||||
@@ -84,9 +74,6 @@ def update_chat_ajax2(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
res_Dict = {}
|
||||
msgs = []
|
||||
Dict = {}
|
||||
@@ -161,9 +148,7 @@ def update_chat_ajax2(request):
|
||||
res_Dict.update({
|
||||
'required_beep': required_beep,
|
||||
})
|
||||
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, status=200)
|
||||
|
||||
except Exception as e:
|
||||
msg = f'update_chat_ajax2 Error = {str(e)}'
|
||||
@@ -178,9 +163,6 @@ def update_chat_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
res_Dict = {}
|
||||
msgs = []
|
||||
Dict = {}
|
||||
@@ -274,17 +256,14 @@ def update_chat_ajax(request):
|
||||
res_Dict.update({
|
||||
'required_beep': required_beep,
|
||||
})
|
||||
|
||||
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, status=200)
|
||||
|
||||
except Exception as e:
|
||||
msg = f'update_chat_ajax Error = {str(e)}'
|
||||
return JsonResponse({'error': msg}, status=400)
|
||||
|
||||
|
||||
# @login_required()#login_url='/profile/login/')
|
||||
# @login_required(login_url='/profile/login/')
|
||||
# def send_msg_ajax(request):
|
||||
# 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):
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
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'
|
||||
Dict.update(get_user_timezone_Dict(request.user, request=request))
|
||||
html = render_to_string(tpl_name, Dict, request=request)
|
||||
|
||||
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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
except Exception as e:
|
||||
msg = f'support_show_chat_by_ticket_ajax Error = {str(e)}'
|
||||
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):
|
||||
from ChatServiceApp.forms import TicketForm
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
Dict = {
|
||||
'form': TicketForm()
|
||||
@@ -474,23 +444,16 @@ def support_create_ticket_form_ajax(request):
|
||||
tpl_name = 'blocks/profile/b_create_ticket.html'
|
||||
|
||||
html = render_to_string(tpl_name, Dict, request=request)
|
||||
|
||||
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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def create_ticket_ajax(request):
|
||||
from ChatServiceApp.forms import TicketForm
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = request.POST
|
||||
@@ -549,8 +512,6 @@ def create_ticket_ajax(request):
|
||||
'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:
|
||||
|
||||
@@ -3,8 +3,6 @@ from .models import *
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
|
||||
class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
||||
|
||||
fieldsets = [
|
||||
@@ -49,7 +47,7 @@ class Admin_StaticPage(Admin_Trans_BaseModelViewPage):
|
||||
if request.user.is_superuser:
|
||||
return True
|
||||
|
||||
if not obj or obj.url in ('main', 'works'):
|
||||
if obj.url in ('main', 'spec_technics', 'works'):
|
||||
return False
|
||||
|
||||
admin.site.register(StaticPage,Admin_StaticPage)
|
||||
|
||||
@@ -1,47 +1,6 @@
|
||||
from django.http import HttpResponse, Http404, FileResponse
|
||||
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):
|
||||
|
||||
from SubscribesApp.funcs import get_cur_user_subscribe
|
||||
@@ -62,7 +21,7 @@ def get_inter_Dict(user):
|
||||
|
||||
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))
|
||||
|
||||
@@ -83,9 +42,4 @@ def get_inter_http_response(template_obj, context_Dict, request):
|
||||
# if text and title and not request.user.is_anonymous:
|
||||
# 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))
|
||||
@@ -13,15 +13,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
|
||||
res = {}
|
||||
opts = opts.values('opt_type', 'value', 'prefix')
|
||||
for item in opts:
|
||||
# if item['opt_type'] == 'domain':
|
||||
#
|
||||
# try:
|
||||
# from django.contrib.sites.models import Site
|
||||
# current_site = Site.objects.get_current()
|
||||
# res.update({item['opt_type']: current_site.domain})
|
||||
# # continue
|
||||
# except Exception as e:
|
||||
# print(str(e))
|
||||
if item['opt_type'] == 'domain':
|
||||
|
||||
try:
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
res.update({item['opt_type']: current_site.domain})
|
||||
continue
|
||||
except Exception as e:
|
||||
print(str(e))
|
||||
|
||||
if item['prefix']:
|
||||
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 ckeditor.fields import RichTextField
|
||||
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):
|
||||
promo_header = models.BooleanField(verbose_name=_('Промо-хэдер'), default=False)
|
||||
@@ -49,6 +29,9 @@ class Option(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)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
@@ -78,7 +78,7 @@ def del_amp_symbols(value):
|
||||
@stringfilter
|
||||
def del_lang_from_path(value):
|
||||
path_list = value.split('/')
|
||||
path = '/' + '/'.join(path_list[4:])
|
||||
path = '/' + '/'.join(path_list[2:])
|
||||
|
||||
# for i in path_list[1:]:
|
||||
# path.join(i + '/')
|
||||
|
||||
@@ -27,9 +27,3 @@ class FAQitem_TranslationOptions(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 = [
|
||||
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('test_code', test_code, name='test_code'),
|
||||
path('generate_routes/<int:routes_count>/', generate_routes, name='generate_routes'),
|
||||
]
|
||||
@@ -1,12 +1,11 @@
|
||||
import json
|
||||
|
||||
from django.http import HttpResponse, Http404, FileResponse, HttpResponseRedirect
|
||||
from django.http import HttpResponse, Http404, FileResponse
|
||||
from django.template import loader, RequestContext
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from .models import *
|
||||
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.views.decorators.http import require_GET, require_POST
|
||||
from django.shortcuts import get_object_or_404
|
||||
@@ -14,125 +13,49 @@ from django.contrib.auth.models import User
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from webpush import send_user_notification
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from django.urls import reverse
|
||||
|
||||
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.models import Route
|
||||
from ReferenceDataApp.models import Airport, City
|
||||
|
||||
res = None
|
||||
|
||||
from_air = Airport.objects.get(iata_code='MSQ')
|
||||
to_air = Airport.objects.get(iata_code='SVO')
|
||||
|
||||
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 = ''
|
||||
# import allauth
|
||||
# from allauth.socialaccount.models import SocialApp
|
||||
# apps = SocialApp.objects.all()
|
||||
# apps.delete()
|
||||
|
||||
from RoutesApp.search_matches import search_matches
|
||||
from RoutesApp.models import Route
|
||||
search_matches(Route.objects.filter(id=17158))
|
||||
search_matches()
|
||||
|
||||
# from RoutesApp.funcs import get_city_by_type_transport_and_address_point
|
||||
# from RoutesApp.models import Route
|
||||
# from ReferenceDataApp.models import Airport, City
|
||||
# try:
|
||||
# # body = request.body
|
||||
# # 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')
|
||||
# to_air = Airport.objects.get(iata_code='SVO')
|
||||
# if not route.to_city:
|
||||
# route.to_city = get_city_by_type_transport_and_address_point(route.type_transport,
|
||||
# route.to_address_point)
|
||||
# required_save = True
|
||||
#
|
||||
# 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(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
|
||||
# if required_save:
|
||||
# route.save()
|
||||
|
||||
return HttpResponse('finished')
|
||||
|
||||
@@ -144,57 +67,12 @@ def Page404(request, exeption=None):
|
||||
|
||||
t = loader.get_template('404.html')
|
||||
try:
|
||||
res = get_inter_http_response(t, Dict, request)
|
||||
res = get_inter_http_respose(t, Dict, request)
|
||||
return HttpResponse(res, status=404)
|
||||
except Exception as 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):
|
||||
@@ -226,14 +104,14 @@ def MainPage(request):
|
||||
Dict.update({'breadcrumbs': breadcrumbs_Dict})
|
||||
|
||||
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))
|
||||
|
||||
|
||||
|
||||
def StaticPageView(request, url):
|
||||
from RoutesApp.forms import RouteForm
|
||||
from SubscribesApp.funcs import get_subscribes_w_options
|
||||
from SubscribesApp.funcs import get_subsribes_w_options
|
||||
|
||||
Dict = {}
|
||||
|
||||
@@ -249,19 +127,13 @@ def StaticPageView(request, url):
|
||||
'route_form': RouteForm(),
|
||||
'owner_type': 'mover'
|
||||
})
|
||||
elif url in ['landing_customer', 'landing_mover']:
|
||||
raise Http404
|
||||
# return HttpResponseRedirect(reverse('customer_landing_page'))
|
||||
# elif url == 'landing_mover':
|
||||
# return HttpResponseRedirect(reverse('mover_landing_page'))
|
||||
|
||||
# elif url == 'works':
|
||||
# return WorksPage(request)
|
||||
elif url in ['main']:
|
||||
raise Http404
|
||||
|
||||
if url in ['for_movers', 'for_customers']:
|
||||
subscribes, all_options = get_subscribes_w_options()
|
||||
subscribes, all_options = get_subsribes_w_options()
|
||||
Dict.update({
|
||||
'subscribes': subscribes,
|
||||
})
|
||||
@@ -276,11 +148,8 @@ def StaticPageView(request, url):
|
||||
'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')
|
||||
return get_inter_http_response(t, Dict, request)
|
||||
return get_inter_http_respose(t, 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.conf import settings
|
||||
from django.utils.translation import gettext as _
|
||||
from SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
||||
|
||||
|
||||
def get_key_Dict():
|
||||
@@ -19,9 +18,6 @@ def get_key_Dict():
|
||||
return Dict
|
||||
|
||||
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:
|
||||
# body = request.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 .models import *
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
class Admin_Country(Admin_Trans_BaseModel):
|
||||
fieldsets = [
|
||||
@@ -11,20 +10,11 @@ class Admin_Country(Admin_Trans_BaseModel):
|
||||
'fields': [
|
||||
'name', 'enable', 'short_code', 'code',
|
||||
]
|
||||
}],
|
||||
[_('Дополнительно'), {
|
||||
'classes': ['wide', 'collapse'],
|
||||
'fields': (
|
||||
'timezone',
|
||||
'geo_lat', 'geo_lon',
|
||||
'json_data',
|
||||
)
|
||||
}],
|
||||
}]
|
||||
]
|
||||
|
||||
list_display = [
|
||||
'id', 'name', 'name_en', 'name_ru',
|
||||
'timezone',
|
||||
'short_code', 'code',
|
||||
'enable', 'area_id', 'parsing_finished_DT',
|
||||
'order', 'modifiedDT', 'createDT']
|
||||
@@ -32,35 +22,18 @@ class Admin_Country(Admin_Trans_BaseModel):
|
||||
admin.site.register(Country, Admin_Country)
|
||||
|
||||
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 = [
|
||||
[None, {
|
||||
'classes': ['wide'],
|
||||
'fields': [
|
||||
'name', 'enable', 'country',
|
||||
]
|
||||
}],
|
||||
[_('Дополнительно'), {
|
||||
'classes': ['wide', 'collapse'],
|
||||
'fields': (
|
||||
'timezone',
|
||||
'geo_lat', 'geo_lon',
|
||||
'json_data',
|
||||
)
|
||||
}],
|
||||
}]
|
||||
]
|
||||
|
||||
list_display = [
|
||||
'id', 'name', 'name_en', 'name_ru',
|
||||
'country',
|
||||
'timezone', 'cur_dt',
|
||||
'enable', 'area_id', 'parsing_finished_DT',
|
||||
'order', 'modifiedDT', 'createDT']
|
||||
search_fields = ['id', 'name_en', 'name_ru', 'country__name']
|
||||
@@ -77,21 +50,12 @@ class Admin_Airport(Admin_Trans_BaseModel):
|
||||
'international_name',
|
||||
# 'area_id'
|
||||
]
|
||||
}],
|
||||
[_('Дополнительно'), {
|
||||
'classes': ['wide', 'collapse'],
|
||||
'fields': (
|
||||
'timezone',
|
||||
'geo_lat', 'geo_lon',
|
||||
'json_data',
|
||||
)
|
||||
}],
|
||||
}]
|
||||
]
|
||||
|
||||
list_display = [
|
||||
'id', 'name', 'name_en', 'name_ru',
|
||||
'city', 'iata_code', 'icao_code',
|
||||
'timezone',
|
||||
'international_name',
|
||||
'enable', 'area_id', 'parsing_finished_DT',
|
||||
'order', 'modifiedDT', 'createDT']
|
||||
|
||||
@@ -3,45 +3,24 @@ from .models import *
|
||||
import hashlib, json
|
||||
from datetime import datetime, timedelta
|
||||
from django.db.models import Q
|
||||
from timezonefinder import TimezoneFinder
|
||||
|
||||
tzf = TimezoneFinder()
|
||||
|
||||
def search_cities_in_db(search_str):
|
||||
res_data = []
|
||||
|
||||
|
||||
|
||||
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)
|
||||
objs = City.objects.filter(Q_obj)
|
||||
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'
|
||||
)
|
||||
|
||||
res_data = City.objects.filter(Q_obj).values('id', 'name', 'country__name')
|
||||
return list(res_data)
|
||||
|
||||
def search_airports_in_db(search_str):
|
||||
res_data = []
|
||||
Q_obj = Q(iata_code__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__country__name_en__icontains=search_str) | \
|
||||
Q(city__country__name_ru__icontains=search_str)
|
||||
objs = Airport.objects.filter(Q_obj)
|
||||
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'
|
||||
)
|
||||
|
||||
res_data = Airport.objects.filter(Q_obj).values('id', 'name', 'iata_code', 'city__name', 'city__country__name')
|
||||
return list(res_data)
|
||||
|
||||
|
||||
@@ -78,39 +57,25 @@ def create_airports_by_airportsList(airportsList, city=None):
|
||||
if airport_Dict['iata']:
|
||||
kwargs.update({'iata_code': airport_Dict['iata']})
|
||||
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:
|
||||
print(f' - - {airport_Dict["iata"]} не найден в БД > добавляем')
|
||||
except Exception as e:
|
||||
print(f'error = {str(e)}')
|
||||
|
||||
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 = {
|
||||
'city': city,
|
||||
|
||||
# 'name_ru': airport_Dict['name:ru'],
|
||||
# 'name_en': airport_Dict['name:en'],
|
||||
'timezone': tz,
|
||||
|
||||
'geo_lat': str(geo_lat),
|
||||
'geo_lon': str(geo_lon),
|
||||
'geo_lat': str(airport_Dict['@lat']),
|
||||
'geo_lon': str(airport_Dict['@lon']),
|
||||
|
||||
'international_name': airport_Dict['int_name'],
|
||||
|
||||
'iata_code': airport_Dict['iata'],
|
||||
'icao_code': airport_Dict['icao'],
|
||||
|
||||
'modifiedDT': datetime.now(),
|
||||
}
|
||||
|
||||
if airport_Dict['name:ru']:
|
||||
@@ -154,10 +119,7 @@ def parse_data():
|
||||
|
||||
country = Country.objects.get(**kwargs)
|
||||
|
||||
if (country.parsing_finished_DT
|
||||
and (datetime.now() - country.parsing_finished_DT).days < 30
|
||||
and country.timezone
|
||||
):
|
||||
if country.parsing_finished_DT and (datetime.now() - country.parsing_finished_DT).days < 30:
|
||||
print(f' + {country.name} - существует в БД, не требует парсинга')
|
||||
continue
|
||||
|
||||
@@ -232,12 +194,6 @@ def parse_data():
|
||||
else:
|
||||
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 = {
|
||||
'country': country,
|
||||
@@ -245,11 +201,8 @@ def parse_data():
|
||||
# 'name_ru': city_Dict['name:ru'],
|
||||
# 'name_en': city_Dict['name:en'],
|
||||
|
||||
'timezone': tz,
|
||||
|
||||
'geo_lat': str(geo_lat),
|
||||
'geo_lon': str(geo_lon),
|
||||
|
||||
'geo_lat': str(city_Dict['@lat']),
|
||||
'geo_lon': str(city_Dict['@lon']),
|
||||
}
|
||||
|
||||
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()
|
||||
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':
|
||||
country.parsing_finished_DT = datetime.now()
|
||||
country.save()
|
||||
country.save(update_fields=['parsing_finished_DT'])
|
||||
|
||||
return True
|
||||
@@ -13,8 +13,7 @@ from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
from django.db.models import Q
|
||||
import json
|
||||
from GeneralApp.funcs import get_inter_http_response
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
from GeneralApp.funcs import get_inter_http_respose
|
||||
|
||||
def get_address_point_ajax(request):
|
||||
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':
|
||||
raise Http404
|
||||
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
@@ -56,12 +52,10 @@ def get_address_point_ajax(request):
|
||||
item['fullname'] = f'{item["iata_code"]} - {item["name"]}'
|
||||
item['city_name'] = item['city__name']
|
||||
item['country_name'] = item['city__country__name']
|
||||
item['city_DT'] = datetime.now(tz=pytz.timezone(item['city__timezone']))
|
||||
else:
|
||||
item['city_name'] = item['name']
|
||||
item['country_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)}"
|
||||
i += 1
|
||||
|
||||
@@ -70,8 +64,6 @@ def get_address_point_ajax(request):
|
||||
'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)
|
||||
|
||||
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 BaseModels.base_models import BaseModel
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from datetime import datetime
|
||||
|
||||
class Country(BaseModel):
|
||||
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_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)
|
||||
|
||||
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)
|
||||
|
||||
timezone = models.CharField(max_length=250, verbose_name=_('Часовая зона'), blank=True, null=True)
|
||||
|
||||
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
@@ -60,17 +54,6 @@ class City(BaseModel):
|
||||
else:
|
||||
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):
|
||||
country = _('Неизвестно')
|
||||
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_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)
|
||||
|
||||
parsing_finished_DT = models.DateTimeField(verbose_name=_('Дата и время завершения парсинга'), blank=True, null=True)
|
||||
|
||||
@@ -3,33 +3,17 @@ from .models import *
|
||||
from django.contrib import admin
|
||||
|
||||
class Admin_Route(Admin_Trans_BaseModel):
|
||||
readonly_fields = [
|
||||
# 'highlight_end_DT',
|
||||
'rising_DT'
|
||||
]
|
||||
list_display = [
|
||||
'id', 'owner_type',
|
||||
'rising_DT',
|
||||
'receive_msg_by_email', 'type_transport', 'cargo_type',
|
||||
'id', 'owner_type', 'receive_msg_by_email', 'type_transport', 'cargo_type',
|
||||
'departure_DT', 'from_city', 'from_place',
|
||||
'arrival_DT', 'to_city', 'to_place', 'owner',
|
||||
'order', 'modifiedDT', 'createDT'
|
||||
]
|
||||
list_editable = ['rising_DT']
|
||||
|
||||
list_display_links = ['id']
|
||||
|
||||
list_filter = [
|
||||
'owner_type', 'type_transport',
|
||||
'rising_DT',
|
||||
'cargo_type',
|
||||
'from_place', 'arrival_DT',
|
||||
'modifiedDT', 'createDT'
|
||||
]
|
||||
list_filter = ['owner_type', 'type_transport', 'cargo_type', 'from_place', 'arrival_DT', 'modifiedDT', 'createDT']
|
||||
search_fields = ['owner__first_name', 'owner__last_name']
|
||||
raw_id_fields = ['from_city', 'to_city']
|
||||
|
||||
search_fields = [
|
||||
'owner__first_name', 'owner__last_name', 'from_city__name', 'to_city__name', 'owner__email'
|
||||
]
|
||||
raw_id_fields = ['from_city', 'to_city', 'owner']
|
||||
|
||||
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):
|
||||
from_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:
|
||||
model = Route
|
||||
exclude = [
|
||||
@@ -64,6 +61,8 @@ class RouteForm(forms.ModelForm):
|
||||
# print('check')
|
||||
cleaned_data = super(RouteForm, self).clean()
|
||||
|
||||
|
||||
|
||||
try:
|
||||
|
||||
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 .forms import *
|
||||
from django.utils.translation import gettext as _
|
||||
from django.template.loader import render_to_string
|
||||
from datetime import datetime, timedelta
|
||||
from django.db.models import F, Q
|
||||
from datetime import datetime
|
||||
|
||||
elements_on_page = 25
|
||||
|
||||
@@ -111,9 +108,9 @@ def get_profile_new_route_page_html(request, data):
|
||||
return html
|
||||
|
||||
|
||||
# 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)
|
||||
# return city.get_country_n_city_str()
|
||||
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)
|
||||
return city.get_country_n_city_str()
|
||||
|
||||
|
||||
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)
|
||||
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):
|
||||
routes_Dict = get_routes_Dict(request.user)
|
||||
@@ -147,11 +134,6 @@ def get_profile_my_routes_page_content_html(request):
|
||||
print(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)
|
||||
return html
|
||||
|
||||
@@ -172,7 +154,6 @@ def get_routes_Dict(user=None, data=None):
|
||||
'owner': user
|
||||
})
|
||||
|
||||
|
||||
from_el = None
|
||||
to_el = None
|
||||
|
||||
@@ -222,19 +203,16 @@ def get_routes_Dict(user=None, data=None):
|
||||
):
|
||||
kwargs.update({key: val})
|
||||
|
||||
if key == 'from_address_point': # в from_address_point всегда город
|
||||
# city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||
city = get_city_by_address_point(val)
|
||||
if key == 'from_address_point':
|
||||
city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||
kwargs.update({f'from_city': city})
|
||||
|
||||
|
||||
res_Dict.update({
|
||||
'from_address_point_txt': city.get_country_n_city_str()
|
||||
})
|
||||
|
||||
if key == 'to_address_point': # в to_address_point всегда город
|
||||
# city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||
city = get_city_by_address_point(val)
|
||||
if key == 'to_address_point':
|
||||
city = get_city_by_type_transport_and_address_point(type_transport, val)
|
||||
kwargs.update({f'to_city': city})
|
||||
res_Dict.update({
|
||||
'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':
|
||||
to_el = int(val)
|
||||
|
||||
# rising_routes = Route.objects.filter(
|
||||
# **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 = Route.objects.filter(**kwargs).order_by('-departure_DT', '-arrival_DT', '-modifiedDT')
|
||||
routes_count = routes.count()
|
||||
|
||||
|
||||
|
||||
|
||||
if from_el and to_el:
|
||||
routes = routes[from_el:to_el]
|
||||
elif from_el:
|
||||
|
||||
@@ -4,8 +4,6 @@ from django.urls import path
|
||||
# from AuthApp.import_funcs import *
|
||||
from .js_views import *
|
||||
|
||||
# /routes/
|
||||
|
||||
urlpatterns = [
|
||||
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'),
|
||||
@@ -16,7 +14,4 @@ urlpatterns = [
|
||||
path('get_routes/', get_my_routes_ajax, name='get_my_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
|
||||
from copy import deepcopy
|
||||
|
||||
from django.shortcuts import render
|
||||
|
||||
@@ -11,114 +10,17 @@ from django.template import loader, RequestContext
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from BaseModels.mailSender import techSendMail
|
||||
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.urls import reverse
|
||||
from .forms 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):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
@@ -138,8 +40,6 @@ def del_route_ajax(request):
|
||||
'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:
|
||||
@@ -154,11 +54,6 @@ def edit_route_ajax(request):
|
||||
if request.method != 'POST':
|
||||
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)
|
||||
|
||||
Dict = {}
|
||||
@@ -193,13 +88,7 @@ def edit_route_ajax(request):
|
||||
return JsonResponse({'errors': msg})
|
||||
|
||||
html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
||||
res_Dict = {
|
||||
'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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
|
||||
@@ -209,10 +98,6 @@ def edit_route_ajax(request):
|
||||
def new_route_view_ajax(request):
|
||||
if request.method != 'POST':
|
||||
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()
|
||||
# Dict = {
|
||||
@@ -238,10 +123,7 @@ def new_route_view_ajax(request):
|
||||
|
||||
|
||||
# html = render_to_string('blocks/profile/b_new_route.html', Dict, request=request)
|
||||
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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
|
||||
def find_routes_ajax(request):
|
||||
@@ -250,8 +132,6 @@ def find_routes_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
|
||||
@@ -265,7 +145,6 @@ def find_routes_ajax(request):
|
||||
if 'errors' in routes_Dict:
|
||||
return JsonResponse(routes_Dict, status=400)
|
||||
|
||||
|
||||
if routes_Dict['routes']:
|
||||
html = render_to_string('blocks/b_search_routes.html', routes_Dict, request=request)
|
||||
else:
|
||||
@@ -278,8 +157,6 @@ def find_routes_ajax(request):
|
||||
# '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)
|
||||
|
||||
except Exception as e:
|
||||
@@ -298,30 +175,11 @@ def get_my_routes_ajax(request):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
data = request.POST.dict()
|
||||
if not data and request.body:
|
||||
data = json.loads(request.body)
|
||||
|
||||
try:
|
||||
|
||||
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)
|
||||
routes_Dict = get_routes_Dict(request.user)
|
||||
if 'errors' in routes_Dict:
|
||||
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)
|
||||
|
||||
@@ -329,8 +187,6 @@ def get_my_routes_ajax(request):
|
||||
'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:
|
||||
@@ -350,13 +206,7 @@ def create_or_change_route_ajax(request, route_id=None):
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
if not check_option_in_cur_user_subscribe(request.user, 'размещение заявок'):
|
||||
return JsonResponse({'html': 'нет доступа'}, status=403)
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
Dict = {}
|
||||
route_old_Dict = None
|
||||
|
||||
try:
|
||||
|
||||
@@ -371,7 +221,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
||||
if route:
|
||||
form = RouteForm(data, instance=route)
|
||||
Dict.update({'route': route})
|
||||
route_old_Dict = deepcopy(route.__dict__)
|
||||
else:
|
||||
form = RouteForm(data)
|
||||
|
||||
@@ -392,16 +241,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
||||
if 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.save()
|
||||
|
||||
@@ -409,11 +248,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
||||
|
||||
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:
|
||||
form.errors.update(routes_Dict['errors'])
|
||||
Dict.update({'form': form})
|
||||
@@ -427,8 +261,6 @@ def create_or_change_route_ajax(request, route_id=None):
|
||||
'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)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -15,16 +15,21 @@ class Command(BaseCommand):
|
||||
print(msg)
|
||||
|
||||
try:
|
||||
from SubscribesApp.funcs import finish_user_subscribes, extension_free_subscribes
|
||||
extension_free_subscribes()
|
||||
finish_user_subscribes()
|
||||
from ...search_matches import search_matches
|
||||
msg = search_matches()
|
||||
if msg:
|
||||
print(msg)
|
||||
except Exception as e:
|
||||
msg = f'every_day_start fail = {str(e)}'
|
||||
msg = f'every_1hour_start search_matches fail = {str(e)}'
|
||||
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)} -')
|
||||
|
||||
@@ -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.utils.translation import gettext_lazy as _
|
||||
from BaseModels.base_models import BaseModel
|
||||
from colorfield.fields import ColorField
|
||||
|
||||
|
||||
type_transport_choices = [
|
||||
@@ -39,8 +38,8 @@ class Route(BaseModel):
|
||||
|
||||
type_transport = models.CharField(
|
||||
choices=type_transport_choices, default='', verbose_name=_('Выберите способ перевозки'))
|
||||
departure_DT = models.DateTimeField(verbose_name=_('Дата и время выезда'))
|
||||
arrival_DT = models.DateTimeField(verbose_name=_('Дата и время прибытия'))
|
||||
departure_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время выезда'))
|
||||
arrival_DT = models.DateTimeField(default=True, verbose_name=_('Дата и время прибытия'))
|
||||
from_address_point = models.IntegerField(verbose_name=_('Пункт выезда'))
|
||||
to_address_point = models.IntegerField(verbose_name=_('Пункт приезда'))
|
||||
from_city = models.ForeignKey(
|
||||
@@ -57,25 +56,12 @@ class Route(BaseModel):
|
||||
verbose_name=_('Куда можете доставить?'))
|
||||
cargo_type = models.CharField(choices=cargo_type_choices, default='parcel', 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)
|
||||
receive_msg_by_email = models.BooleanField(default=False, verbose_name=_('Получать уведомления по E-mail'))
|
||||
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)
|
||||
|
||||
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):
|
||||
if self.name:
|
||||
return f'{self.name}'
|
||||
@@ -88,29 +74,6 @@ class Route(BaseModel):
|
||||
verbose_name_plural = _(u'Маршруты')
|
||||
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):
|
||||
res = _('Неизвестно')
|
||||
if self.from_city:
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
|
||||
from django.template.loader import render_to_string
|
||||
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 SubscribesApp.funcs import check_option_in_cur_user_subscribe
|
||||
|
||||
|
||||
|
||||
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:
|
||||
return None
|
||||
|
||||
if not check_option_in_cur_user_subscribe(route.owner, 'push уведомления'):
|
||||
return False
|
||||
|
||||
from PushMessages.views import send_push
|
||||
title = 'Мы нашли исполнителя по Вашему объявлению!'
|
||||
text = 'Для просмотра результата нажмите на кнопку ниже'
|
||||
@@ -47,7 +44,7 @@ def send_push_message_for_found_matches_routes(route, data_Dict):
|
||||
|
||||
|
||||
|
||||
def send_mail_found_matches_routes(route, matched_route, data_Dict):
|
||||
def send_mail_found_matches_routes(route, data_Dict):
|
||||
print(f'send_mail_found_matches_routes to route id = {route.id}')
|
||||
|
||||
Dict = {
|
||||
@@ -59,7 +56,7 @@ def send_mail_found_matches_routes(route, matched_route, data_Dict):
|
||||
|
||||
|
||||
mail_sets = get_mail_send_options()
|
||||
to = [route.owner.email]
|
||||
to = [route.owner.email, 'web@syncsystems.net']
|
||||
subject = _('Мы нашли исполнителя по Вашему объявлению!')
|
||||
res = admin_send_mail_by_SMTPlib(
|
||||
mail_sets,
|
||||
@@ -68,68 +65,9 @@ def send_mail_found_matches_routes(route, matched_route, data_Dict):
|
||||
html_content=html
|
||||
)
|
||||
|
||||
subject = f'route matches {route.id} <> {matched_route.id} send to {route.owner.email}'
|
||||
to = ['web@syncsystems.net', 'sa@a3-global.com']
|
||||
res = admin_send_mail_by_SMTPlib(
|
||||
mail_sets,
|
||||
subject=subject,
|
||||
from_email=mail_sets['sender_email'], to=to,
|
||||
html_content=html
|
||||
)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def user_notify_by_result_search_matches(route_for_send, founded_route, params):
|
||||
log = ''
|
||||
|
||||
data_Dict = None
|
||||
try:
|
||||
data_Dict = get_Dict_for_send_msgs(params, founded_route.owner_type)
|
||||
except Exception as e:
|
||||
msg = f'<br>\n! search_matches Error get_Dict_for_send_msgs = {str(e)}'
|
||||
print(msg)
|
||||
log += msg
|
||||
|
||||
if data_Dict and check_option_in_cur_user_subscribe(
|
||||
route_for_send.owner, 'push уведомления'
|
||||
):
|
||||
try:
|
||||
msg = send_push_message_for_found_matches_routes(route_for_send, 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_for_send.owner,
|
||||
'уведомление на e-mail о появлении перевозчика по заданным критериям'
|
||||
):
|
||||
try:
|
||||
msg = send_mail_found_matches_routes(route_for_send, founded_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
|
||||
|
||||
return log
|
||||
|
||||
|
||||
|
||||
def users_notify_by_result_search_matches(source_route, found_routes, params):
|
||||
log = ''
|
||||
log += user_notify_by_result_search_matches(source_route, found_routes[0], params)
|
||||
|
||||
for route in found_routes:
|
||||
log += user_notify_by_result_search_matches(route, source_route, params)
|
||||
|
||||
return log
|
||||
|
||||
|
||||
def search_matches(for_routes=None):
|
||||
print('search_matches')
|
||||
|
||||
@@ -143,11 +81,8 @@ def search_matches(for_routes=None):
|
||||
)
|
||||
|
||||
check_fields = [
|
||||
'type_transport', 'departure_DT', 'arrival_DT',
|
||||
# 'from_address_point', 'to_address_point',
|
||||
'from_place', 'to_place',
|
||||
'cargo_type', 'weight',
|
||||
'from_city', 'to_city',
|
||||
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
|
||||
'from_place', 'to_place', 'cargo_type', 'weight'
|
||||
]
|
||||
|
||||
if for_routes:
|
||||
@@ -168,20 +103,11 @@ def search_matches(for_routes=None):
|
||||
kwargs.update({f"{field_name}__date": field_val.date()})
|
||||
elif field_name == 'weight':
|
||||
# print(field_name)
|
||||
params.update({f"{field_name}": field_val})
|
||||
if route.owner_type == 'mover':
|
||||
# params.update({f"{field_name}__lte": field_val})
|
||||
kwargs.update({f"{field_name}__lte": field_val})
|
||||
else:
|
||||
# params.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:
|
||||
kwargs.update({field_name: field_val})
|
||||
params.update({field_name: field_val})
|
||||
@@ -199,9 +125,14 @@ def search_matches(for_routes=None):
|
||||
|
||||
if found_routes:
|
||||
msg = f'found routes for send messages = {found_routes.count()}'
|
||||
print(msg)
|
||||
|
||||
log += users_notify_by_result_search_matches(route, found_routes, params)
|
||||
data_Dict = get_Dict_for_send_msgs(params, found_routes[0].owner_type)
|
||||
msg = send_push_message_for_found_matches_routes(route, data_Dict)
|
||||
if msg:
|
||||
log += msg
|
||||
msg = send_mail_found_matches_routes(route, data_Dict)
|
||||
if msg:
|
||||
log += msg
|
||||
|
||||
except Exception as 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 .funcs 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):
|
||||
|
||||
Dict = {}
|
||||
data = {}
|
||||
data = None
|
||||
|
||||
try:
|
||||
if request.GET:
|
||||
data = request.GET.dict()
|
||||
|
||||
if request.GET:
|
||||
data = request.GET.dict()
|
||||
routes_Dict = get_routes_Dict(data=data)
|
||||
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)
|
||||
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)})
|
||||
title = _('Результат поиска маршрутов')
|
||||
if 'from_address_point_txt' in data:
|
||||
title = f'{title} из {data["from_address_point_txt"]}'
|
||||
if 'to_address_point_txt' in data:
|
||||
title = f'{title} в {data["to_address_point_txt"]}'
|
||||
|
||||
title = _('Результат поиска маршрутов')
|
||||
if 'from_address_point_txt' in data:
|
||||
title = f'{title} из {data["from_address_point_txt"]}'
|
||||
if 'to_address_point_txt' in data:
|
||||
title = f'{title} в {data["to_address_point_txt"]}'
|
||||
Dict.update({
|
||||
'page': {
|
||||
'title': title,
|
||||
'description': title,
|
||||
'keywords': title,
|
||||
}
|
||||
})
|
||||
|
||||
Dict.update({
|
||||
'page': {
|
||||
'title': title,
|
||||
'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
|
||||
t = loader.get_template('pages/p_results_find_route.html')
|
||||
return get_inter_http_respose(t, Dict, request)
|
||||
# return HttpResponse(t.render(Dict, request))
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
}),
|
||||
(None, {
|
||||
'classes': ['wide'],
|
||||
'fields': (
|
||||
('allow_route_rising_count',),
|
||||
('allow_route_highlight_count', 'route_highlight_hours'),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
list_display = [
|
||||
'id', 'enable',
|
||||
'name',
|
||||
'allow_route_rising_count',
|
||||
'allow_route_highlight_count', 'route_highlight_hours',
|
||||
'order', 'modifiedDT', 'createDT'
|
||||
]
|
||||
list_editable = ['enable']
|
||||
@@ -72,7 +63,7 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'classes': ['wide'],
|
||||
'fields': ('enable',
|
||||
'fields': ('name',
|
||||
'user', 'subscribe',
|
||||
'last_paid_DT',
|
||||
'paid_period_from_DT', 'paid_period_to_DT',
|
||||
@@ -83,9 +74,8 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
||||
)
|
||||
|
||||
list_display = [
|
||||
'id', 'enable',
|
||||
'id',
|
||||
'name', 'user', 'subscribe',
|
||||
'used_route_rising_count', 'used_route_highlight_count',
|
||||
'last_paid_DT', 'paid_period_from_DT', 'paid_period_to_DT',
|
||||
'auto_continue', 'receive_finish_subscribe_msg',
|
||||
'order', 'modifiedDT', 'createDT'
|
||||
@@ -98,7 +88,6 @@ class Admin_SubscribeForUser(Admin_Trans_BaseModel):
|
||||
'auto_continue', 'receive_finish_subscribe_msg',
|
||||
'modifiedDT', 'createDT'
|
||||
]
|
||||
list_editable = ['enable']
|
||||
search_fields = ['name', 'id', 'user__email', 'user__first_name', 'user__last_name']
|
||||
search_fields = ['name']
|
||||
|
||||
admin.site.register(SubscribeForUser,Admin_SubscribeForUser)
|
||||
@@ -1,197 +1,41 @@
|
||||
from .models import *
|
||||
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):
|
||||
|
||||
if not user or not user.is_active or not user.is_authenticated:
|
||||
return None
|
||||
|
||||
user_subscribe = None
|
||||
try:
|
||||
user_subscribe = SubscribeForUser.objects.get(enable=True, user=user)
|
||||
except SubscribeForUser.DoesNotExist:
|
||||
user_subscribe = subscribe_user_to_null_price_subscribe(user)
|
||||
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()
|
||||
user_subscribe = SubscribeForUser.objects.get(user=user)
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
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)
|
||||
subscribes = Subscribe.objects.filter(enable=True)
|
||||
for subscribe in subscribes:
|
||||
subscribe_options_ids = subscribe.options.values_list('id', flat=True)
|
||||
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
|
||||
|
||||
|
||||
def check_n_enable_subscribe_by_order(order):
|
||||
|
||||
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):
|
||||
def get_profile_subscribe_page_content_html(request):
|
||||
|
||||
try:
|
||||
|
||||
from GeneralApp.funcs import get_and_set_lang
|
||||
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']
|
||||
# data = json.loads(request.body)
|
||||
# all_options = SubscribeOption.objects.filter(enable=True)
|
||||
subscribes, all_options = get_subsribes_w_options()
|
||||
|
||||
|
||||
subscribes = []
|
||||
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:
|
||||
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
|
||||
if not subscribe_for_user:
|
||||
tpl_name = 'blocks/profile/b_subscribe_variants.html'
|
||||
else:
|
||||
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_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 = {
|
||||
'subscribe_for_user': subscribe_for_user,
|
||||
'subscribes': subscribes,
|
||||
'subscribes': subscribes
|
||||
}
|
||||
|
||||
html = render_to_string(tpl_name, Dict, request=request)
|
||||
return {
|
||||
'html': html,
|
||||
'check_orders_required': check_orders_required,
|
||||
}
|
||||
return html
|
||||
|
||||
except Exception as 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 RoutesApp.js_views import new_route_view_ajax
|
||||
|
||||
# /subscribes/receive_finish_subscribe_msg/
|
||||
|
||||
urlpatterns = [
|
||||
path('show_cur_subscribe/', show_cur_subscribe_ajax, name='show_cur_subscribe_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('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'),
|
||||
|
||||
@@ -3,7 +3,7 @@ from django.shortcuts import render
|
||||
from uuid import uuid1
|
||||
from .models import *
|
||||
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.contrib.auth.decorators import login_required
|
||||
from BaseModels.mailSender import techSendMail
|
||||
@@ -16,80 +16,36 @@ import json
|
||||
from datetime import datetime, time, timedelta
|
||||
from channels.layers import get_channel_layer
|
||||
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)
|
||||
|
||||
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/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def subscribe_now_ajax(request):
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
try:
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
subscribe = Subscribe.objects.get(id=data['subscribe_id'])
|
||||
|
||||
kwargs_for_order = {
|
||||
kwargs = {
|
||||
'user': request.user,
|
||||
'subscribe': subscribe,
|
||||
'currency': 'KZT',
|
||||
'sum': subscribe.price,
|
||||
'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 = None
|
||||
|
||||
if subscribe.price > 0:
|
||||
from BillingApp.funcs import create_subscribe_order
|
||||
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)
|
||||
subscribe_for_user = SubscribeForUser.objects.filter(user=request.user)
|
||||
if subscribe_for_user:
|
||||
subscribe_for_user.update(**kwargs)
|
||||
subscribe_for_user = subscribe_for_user[0]
|
||||
else:
|
||||
subscribe_for_user = subscribe_user_to_null_price_subscribe(request.user)
|
||||
|
||||
# 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]
|
||||
subscribe_for_user = SubscribeForUser.objects.create(**kwargs)
|
||||
|
||||
if not subscribe_for_user:
|
||||
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)
|
||||
|
||||
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)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
except Exception as e:
|
||||
msg = f'show_cur_subscribe_ajax Error = {str(e)}'
|
||||
return JsonResponse({'error': msg}, status=400)
|
||||
|
||||
|
||||
@login_required()#login_url='/profile/login/')
|
||||
@login_required(login_url='/profile/login/')
|
||||
def show_cur_subscribe_ajax(request):
|
||||
|
||||
if request.method != 'POST':
|
||||
raise Http404
|
||||
|
||||
lang = get_and_set_lang(request)
|
||||
|
||||
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)
|
||||
html = get_profile_subscribe_page_content_html(request)
|
||||
return JsonResponse({'html': html}, status=200)
|
||||
|
||||
# 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,14 +0,0 @@
|
||||
# Generated by Django 4.2.2 on 2025-02-17 17:48
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('SubscribesApp', '0004_alter_subscribe_bg_color_alter_subscribe_text_color'),
|
||||
('SubscribesApp', '0007_subscribeoption_route_highlight_hours'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
@@ -1,29 +1,10 @@
|
||||
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 django.utils.translation import gettext_lazy as _
|
||||
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):
|
||||
|
||||
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:
|
||||
verbose_name = _('Опция подписки')
|
||||
verbose_name_plural = _('Опции подписки')
|
||||
@@ -35,8 +16,7 @@ class Subscribe(BaseModel):
|
||||
|
||||
price = models.FloatField(verbose_name='Стоимость', default=0)
|
||||
options = models.ManyToManyField(
|
||||
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True,
|
||||
related_name='rel_subscribes_for_option'
|
||||
SubscribeOption, verbose_name=_('Подключенные опции'), blank=True, related_name='rel_subscribes_for_option'
|
||||
)
|
||||
period_name = models.CharField(max_length=250, verbose_name=_('Название периода'))
|
||||
period = models.IntegerField(default=0, verbose_name=_('Длительность подписки в часах'))
|
||||
@@ -44,13 +24,6 @@ class Subscribe(BaseModel):
|
||||
bg_color = ColorField(default='#FFFFFF', 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:
|
||||
verbose_name = _('Подписка')
|
||||
verbose_name_plural = _('Подписки')
|
||||
@@ -74,80 +47,6 @@ class SubscribeForUser(BaseModel):
|
||||
receive_finish_subscribe_msg = models.BooleanField(
|
||||
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:
|
||||
verbose_name = _('Пользовательская подписка')
|
||||
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
|
||||
verbose_name_plural = _('Пользовательские подписки')
|
||||
@@ -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 decouple import config
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
@@ -29,22 +30,13 @@ DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
# https://web-push-codelab.glitch.me/
|
||||
|
||||
WEBPUSH_SETTINGS = {
|
||||
"VAPID_PUBLIC_KEY": "BNUNtlKRY-9h2rFemuT6cODbg1Lkl9zMJJl9vcoVxoSXOYTpT-y8iHIseTsrzsSH03462tjYNx38fTkWyumKyEM",
|
||||
"VAPID_PRIVATE_KEY": "ECoHc1i_XcLEo6KmkF76sHvdk49qBA4aNFyns6N3fPs",
|
||||
"VAPID_ADMIN_EMAIL": "tripwithbonus@gmail.com"
|
||||
"VAPID_PUBLIC_KEY": "BKS8byh3MucwCF2h06JY9oey1s1RYII09j-j3ehI3qTYhs965UHv0qNPl-jFjQBbIJCvjVXm9RW6t_oJJK8yMOk",
|
||||
"VAPID_PRIVATE_KEY": "f5NMgOntBtRqsyeKwEzloK-051ggMnZGF_GFimERY0w",
|
||||
"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
|
||||
ACCOUNT_DEFAULT_HTTP_PROTOCOL='https'
|
||||
@@ -54,9 +46,7 @@ ACCOUNT_USERNAME_REQUIRED = False
|
||||
ACCOUNT_AUTHENTICATION_METHOD = 'email'
|
||||
ACCOUNT_EMAIL_VERIFICATION = 'optional'
|
||||
LOGIN_REDIRECT_URL = '/profile/page/dashboard/'
|
||||
# LOGIN_URL = '/profile/login/'
|
||||
from django.urls import reverse_lazy
|
||||
LOGIN_URL = reverse_lazy('login_profile')
|
||||
LOGIN_URL = '/profile/login/'
|
||||
|
||||
LOGOUT_REDIRECT_URL = '/profile/login/'
|
||||
|
||||
@@ -71,7 +61,6 @@ AUTHENTICATION_BACKENDS = [
|
||||
]
|
||||
|
||||
|
||||
|
||||
SOCIALACCOUNT_PROVIDERS = {
|
||||
'google': {
|
||||
'SCOPE': [
|
||||
@@ -104,8 +93,6 @@ INSTALLED_APPS = [
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.humanize',
|
||||
|
||||
'django.contrib.sitemaps',
|
||||
|
||||
'django.contrib.sites',
|
||||
|
||||
'colorfield',
|
||||
@@ -120,8 +107,6 @@ INSTALLED_APPS = [
|
||||
'allauth.socialaccount',
|
||||
'allauth.socialaccount.providers.google',
|
||||
|
||||
'rosetta',
|
||||
|
||||
'GeneralApp',
|
||||
'AuthApp',
|
||||
'RoutesApp',
|
||||
@@ -129,7 +114,6 @@ INSTALLED_APPS = [
|
||||
'ArticlesApp',
|
||||
'SubscribesApp',
|
||||
'PushMessages',
|
||||
'BillingApp',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -173,8 +157,7 @@ TEMPLATES = [
|
||||
# WSGI_APPLICATION = 'TWB.wsgi.application'
|
||||
ASGI_APPLICATION = 'TWB.asgi.application'
|
||||
|
||||
# WS_ADDRESS = 'localhost:8000'
|
||||
WS_ADDRESS = 'tripwb.com'
|
||||
WS_ADDRESS = 'localhost:8000'
|
||||
|
||||
CHANNEL_LAYERS = {
|
||||
'default': {
|
||||
@@ -189,11 +172,8 @@ CHANNEL_LAYERS = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
POSTGRES_DB = config('POSTGRES_DB')
|
||||
POSTGRES_USER = config('POSTGRES_USER')
|
||||
|
||||
|
||||
# Database
|
||||
@@ -202,8 +182,8 @@ CHANNEL_LAYERS = {
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'twbDB',
|
||||
'USER': 'test_user',
|
||||
'NAME': POSTGRES_DB,
|
||||
'USER': POSTGRES_USER,
|
||||
'PASSWORD': 'test_db_pass',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '5432',
|
||||
@@ -266,7 +246,6 @@ LOCALE_PATHS = (
|
||||
|
||||
|
||||
|
||||
|
||||
gettext = lambda s: s
|
||||
LANGUAGES = (
|
||||
(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
|
||||
ROSETTA_SHOW_AT_ADMIN_PANEL = True
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
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 = {
|
||||
|
||||
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.urls import path, include, re_path
|
||||
from django.urls import path, include
|
||||
from django.conf.urls.static import static
|
||||
from django.conf import settings
|
||||
from GeneralApp.views import Page404
|
||||
from AuthApp.views import login_View
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
handler404 = Page404
|
||||
|
||||
urlpatterns = [
|
||||
# path('admin/', admin.site.urls),
|
||||
path('ckeditor/', include('ckeditor_uploader.urls')),
|
||||
path('i18n/', include('django.conf.urls.i18n')),
|
||||
|
||||
@@ -41,8 +38,8 @@ urlpatterns = [
|
||||
path('test_404', Page404, name='page_404'),
|
||||
|
||||
path('', include('PushMessages.urls')),
|
||||
path('', include('SubscribesApp.urls')),
|
||||
|
||||
path('', include('SitemapApp.urls')),
|
||||
]
|
||||
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
@@ -57,13 +54,7 @@ urlpatterns += i18n_patterns(
|
||||
|
||||
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)
|
||||
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
|
||||
psycopg2-binary==2.9.6
|
||||
requests
|
||||
Pillow==9.5.0
|
||||
django-modeltranslation==0.18.10
|
||||
overpass
|
||||
geopy
|
||||
@@ -10,11 +9,9 @@ channels==4.0.0
|
||||
daphne==4.0.0
|
||||
channels-redis==4.1.0
|
||||
django-colorfield
|
||||
django-webpush==0.3.6
|
||||
django-webpush==0.3.5
|
||||
django-allauth==0.60.0
|
||||
pytz==2024.1
|
||||
requests-pkcs12==1.24
|
||||
#django-tz-detect==0.4.0
|
||||
django-rosetta==0.10.0
|
||||
timezonefinder==6.5.2
|
||||
|
||||
celery==5.3.6
|
||||
djangorestframework==3.14.0
|
||||
python-decouple==3.8
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: */admin/*
|
||||
Disallow: /
|
||||
|
||||
Host: tripwb.com
|
||||
@@ -1,10 +1,6 @@
|
||||
from BaseModels.admin_utils import (
|
||||
Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline,
|
||||
AdminImageWidget, get_image_thumb
|
||||
)
|
||||
from BaseModels.admin_utils import Admin_GenericBaseIconStackedInline, Admin_BaseIconModel, GenericStackedInline
|
||||
from copy import deepcopy
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
|
||||
|
||||
class Admin_BaseModel(Admin_BaseIconModel):
|
||||
@@ -90,69 +86,24 @@ class AdminTranslationBase(TranslationAdmin):
|
||||
'screen': ('modeltranslation/css/tabbed_translation_fields.css',),
|
||||
}
|
||||
|
||||
from modeltranslation.admin import TranslationGenericStackedInline, TranslationGenericTabularInline
|
||||
class TranslationGenericTabularInlineCustom(TranslationGenericTabularInline):
|
||||
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 modeltranslation.admin import TranslationGenericStackedInline
|
||||
class AdminStacked_FAQitem(TranslationGenericStackedInline):
|
||||
from GeneralApp.models import FAQitem
|
||||
model = FAQitem
|
||||
extra = 0
|
||||
fields = ['order', 'question', 'answer']
|
||||
|
||||
class Media:
|
||||
|
||||
|
||||
class AdminTabular_Mediaitem(TranslationGenericTabularInlineCustom):
|
||||
from GeneralApp.models import MediaItem
|
||||
model = MediaItem
|
||||
extra = 0
|
||||
fields = ['order', 'video', 'picture']
|
||||
|
||||
|
||||
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 Admin_BaseModelViewPage(Admin_BaseIconModel):
|
||||
pass
|
||||
@@ -178,7 +129,7 @@ class Admin_BaseModelViewPage(Admin_BaseIconModel):
|
||||
# else:
|
||||
# return {}
|
||||
#
|
||||
inlines = [AdminStacked_FAQitem, AdminTabular_Mediaitem]
|
||||
inlines = [AdminStacked_FAQitem]
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@media (max-width: 1280px){
|
||||
|
||||
.remove_route{
|
||||
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -116,19 +116,11 @@
|
||||
}
|
||||
@media (max-width: 1180px){
|
||||
|
||||
.container_inf_about_moving{
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.input_list.find_route{
|
||||
left: unset;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.dropdown{
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.handler_curtain_left{
|
||||
display: block;
|
||||
}
|
||||
@@ -144,10 +136,6 @@
|
||||
transition: 200ms;
|
||||
}
|
||||
|
||||
.unsubscribe_info {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.container_content_handler_curtain_left{
|
||||
display: flex;
|
||||
rotate: 90deg;
|
||||
@@ -266,7 +254,7 @@
|
||||
}
|
||||
|
||||
header{
|
||||
padding: 3px 16px;
|
||||
padding: 5px 16px;
|
||||
margin-top: unset;
|
||||
}
|
||||
.header_logo, .header_btn_mover, .header_btn_sender{
|
||||
@@ -371,7 +359,7 @@
|
||||
|
||||
|
||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
||||
width: 98%;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
@@ -398,14 +386,11 @@
|
||||
margin-left: 5px;
|
||||
}
|
||||
.header_logo_mobile {
|
||||
margin-right: 20px;
|
||||
margin-right: 37px;
|
||||
}
|
||||
.line_f_header{
|
||||
top: 43px;
|
||||
}
|
||||
header .header-second{
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.self_news_img{
|
||||
width: 40%;
|
||||
@@ -509,9 +494,7 @@
|
||||
|
||||
.footer_logo{
|
||||
text-align: center;
|
||||
margin: 40px auto;
|
||||
max-width: 90px;
|
||||
/*margin-left: 43%;*/
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.footer_text_sub{
|
||||
@@ -734,7 +717,7 @@
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
ч
|
||||
|
||||
.arrange_subscribe{
|
||||
margin: 20px auto 20px auto;
|
||||
}
|
||||
@@ -1118,12 +1101,9 @@
|
||||
.left-part-carrier-card, .inf_carrier_container{
|
||||
width: unset;
|
||||
float: none;
|
||||
padding: 1px 20px;
|
||||
padding: 1px 15px;
|
||||
border-right: unset;
|
||||
}
|
||||
.control_frame{
|
||||
top: 3px;
|
||||
}
|
||||
.inf_carrier_container{
|
||||
padding-top: 70px;
|
||||
padding-bottom: 10px;
|
||||
@@ -1153,7 +1133,7 @@
|
||||
.cargo_type_trans{
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
float: unset;
|
||||
/*float: unset;*/
|
||||
}
|
||||
|
||||
.from-to-country-container-carrier{
|
||||
@@ -1201,7 +1181,7 @@
|
||||
.from-to-city-text{
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
/*padding-bottom: 10px;*/
|
||||
padding-bottom: 10px;
|
||||
/*padding-top: unset;*/
|
||||
}
|
||||
.arrow_inf_about_moving{
|
||||
@@ -1214,7 +1194,6 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
margin-top: 7px;
|
||||
}
|
||||
.inf_carrier_icon{
|
||||
width: 20px;
|
||||
@@ -1229,7 +1208,7 @@
|
||||
padding-right: unset;
|
||||
font-size: 14px;
|
||||
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-text-fill-color: transparent;
|
||||
}
|
||||
@@ -1239,7 +1218,6 @@
|
||||
|
||||
.name_carrier{
|
||||
font-size: 14px;
|
||||
position: unset;
|
||||
|
||||
}
|
||||
|
||||
@@ -1345,10 +1323,6 @@
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
.subscribe_wrpapper{
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.text_another_subscribe{
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
@@ -1510,19 +1484,11 @@
|
||||
width: 153px;
|
||||
}
|
||||
|
||||
.popup_content{
|
||||
width: 41%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 950px){
|
||||
|
||||
|
||||
#title_static_small{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.info_profile{
|
||||
width: 65%;
|
||||
float: none;
|
||||
@@ -1558,9 +1524,6 @@
|
||||
.pag_news_item_text{
|
||||
width: unset;
|
||||
}
|
||||
.popup_content{
|
||||
width: 52%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 850px){
|
||||
|
||||
@@ -1605,7 +1568,7 @@
|
||||
|
||||
|
||||
|
||||
.read_more_about_subscribe, .read_more_about_subscribe.error {
|
||||
.read_more_about_subscribe{
|
||||
padding: 0 14px;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
@@ -1664,21 +1627,15 @@
|
||||
|
||||
.toggle_switch_cont{
|
||||
margin-top: 6px;
|
||||
width: unset;
|
||||
width: 12%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
|
||||
|
||||
.line_inf_about_moving{
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.marker_messages_mobile{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -1694,9 +1651,6 @@
|
||||
.marker_messages_mobile.show{
|
||||
display: block;
|
||||
}
|
||||
.popup_content>.confirm_profile_btn{
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 828px){
|
||||
@@ -1730,9 +1684,8 @@
|
||||
|
||||
}
|
||||
|
||||
|
||||
.subscribe_wrpapper{
|
||||
flex-direction: column;
|
||||
.another_subscribe {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.dropdown-content-lang{
|
||||
z-index: 1 ;
|
||||
}
|
||||
|
||||
.menu_buttons.right.open .handler_menu{
|
||||
background: #FFFFFF;
|
||||
color: #000000;
|
||||
@@ -1843,20 +1792,14 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.subscribe_wrpapper{
|
||||
padding: 10px;
|
||||
.another_subscribe{
|
||||
padding: 10px;
|
||||
flex-direction: unset;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
.inf_carrier_icon{
|
||||
/*width: 3%;*/
|
||||
}
|
||||
.popup_content{
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
@media (max-width: 687px){
|
||||
/*.to_address_point_txt.find_route {*/
|
||||
@@ -1865,10 +1808,6 @@
|
||||
/*.from_address_point_txt.find_route.first {*/
|
||||
/* width: 52.1%;*/
|
||||
/*}*/
|
||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
|
||||
.container_inf_about_moving {
|
||||
width: 97%;
|
||||
@@ -1909,10 +1848,6 @@
|
||||
|
||||
|
||||
|
||||
.info_profile>div>div>.left-part-carrier-card>.container_inf_about_moving{
|
||||
width: 89%;
|
||||
}
|
||||
|
||||
.phones_carrier{
|
||||
display: block;
|
||||
}
|
||||
@@ -1938,7 +1873,6 @@
|
||||
|
||||
.container_inf_about_moving{
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.arrow_inf_about_moving{
|
||||
@@ -1959,11 +1893,6 @@
|
||||
margin-bottom: unset;
|
||||
}
|
||||
|
||||
.name_carrier{
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.splitter-from-to-country{
|
||||
@@ -2040,7 +1969,7 @@
|
||||
}
|
||||
|
||||
.dropdown-content{
|
||||
width: 202px;
|
||||
width: 190px;
|
||||
top: 27px;
|
||||
left: -83px;
|
||||
}
|
||||
@@ -2095,13 +2024,9 @@
|
||||
|
||||
.another_subscribe{
|
||||
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user