Merge remote-tracking branch 'origin/main'

This commit is contained in:
2024-01-12 17:42:00 +03:00
20 changed files with 352 additions and 27 deletions

View File

@@ -126,7 +126,7 @@ def send_message_ajax(request):
return JsonResponse({'html': html}, status=400)
Dict = {
'logo': f'{request.scheme}://{sets["domain"]}/static/img/svg/LogoMobile.svg',
'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',
'project_name': sets['project_name'],
'message_title': subject,
'message_text': f'<p><b>{_("ДАННЫЕ ЗАПРОСА")}</b></p>'

View File

@@ -10,8 +10,15 @@ def get_options_by_opt_types(opt_types, only_vals=False):
opts = Option.objects.filter(**kwargs)
if opts and only_vals:
opts = opts.values('opt_type', 'value')
opts = {item['opt_type']: item['value'] for item in opts}
res = {}
opts = opts.values('opt_type', 'value', 'prefix')
for item in opts:
if item['prefix']:
res.update({item['opt_type']: f"{item['prefix']}{item['value']}"})
else:
res.update({item['opt_type']: f"{item['value']}"})
return res
return opts
def get_first_option_value_by_opt_type(opt_type):

View File

@@ -19,18 +19,21 @@ def test_code(request):
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"})
from RoutesApp.search_matches import search_matches
search_matches()
# 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()
#
@@ -49,7 +52,7 @@ def test_code(request):
# if required_save:
# route.save()
# return HttpResponse('finished')
return HttpResponse('finished')

View File

@@ -4,7 +4,7 @@ from django.contrib import admin
class Admin_Route(Admin_Trans_BaseModel):
list_display = [
'id', 'owner_type', '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'
@@ -14,5 +14,6 @@ class Admin_Route(Admin_Trans_BaseModel):
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']
admin.site.register(Route,Admin_Route)

View File

@@ -23,6 +23,7 @@ class RouteForm(forms.ModelForm):
try:
if 'phone' in cleaned_data and 'phone' in cleaned_data:
from BaseModels.validators.form_field_validators import get_phone_valid_error
error = get_phone_valid_error(cleaned_data["phone"])

View File

@@ -154,10 +154,13 @@ def get_routes_Dict(user=None, data=None):
if val:
if key == 'weight':
weight_list = val.split(';')
if weight_list[0]:
kwargs.update({f'{key}__gte': int(weight_list[0])})
if weight_list[1]:
kwargs.update({f'{key}__lte': int(weight_list[1])})
if len(weight_list) > 1:
if weight_list[0]:
kwargs.update({f'{key}__gte': int(weight_list[0])})
if weight_list[1]:
kwargs.update({f'{key}__lte': int(weight_list[1])})
else:
kwargs.update({f'{key}__lte': int(weight_list[0])})
if key == 'type_transport':
items_list = val.split(',')

View File

@@ -230,7 +230,7 @@ def create_or_change_route_ajax(request, route_id=None):
return JsonResponse({'html': html}, status=400)
obj = form.save(commit=False)
if 'owner_type' in data:
if 'owner_type' in data and data['owner_type']:
obj.owner_type = data['owner_type']
if obj.from_address_point:

View File

View File

@@ -0,0 +1,36 @@
from django.core.management.base import BaseCommand
from datetime import datetime
from BaseModels.mailSender import techSendMail
from GeneralApp.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 ...search_matches import search_matches
msg = search_matches()
if msg:
print(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 msg:
techSendMail(mail_sets, str(msg), title='every_1hour_start get_competitors_prices')
print(f'- processing time = {str(datetime.now() - log_begin_DT)} -')

View File

@@ -0,0 +1,13 @@
from django.core.management.base import BaseCommand
from datetime import datetime
class Command(BaseCommand):
def handle(self, *args, **options):
# from B2BApp.funcs import assign_contracts_for_orders_by_tmp_data
# log = assign_contracts_for_orders_by_tmp_data()
from GeneralApp.views import test_code
test_code(None)
self.stdout.write(u'fix_code end')

101
RoutesApp/search_matches.py Normal file
View File

@@ -0,0 +1,101 @@
from .models import *
from datetime import datetime, timedelta
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
def send_mail_found_matches_routes(route, kwargs, search_owner_type):
Dict = {
'route': route,
'search_owner_type': search_owner_type
}
sets = get_options_by_opt_types(['domain', 'project_name'], only_vals=True)
Dict.update(sets)
Dict.update({'logo': f'{sets["domain"]}/static/img/svg/LogoMobile.svg',})
find_routes_page_url = f'{sets["domain"]}/routes/route_search_results/?'
kwargs_list = [f'{key}={value}' for key, value in kwargs.items()]
kwargs_list.append(f'owner_type={search_owner_type}')
find_routes_page_url += f'{"&".join(kwargs_list)}'
Dict.update({'find_routes_page_url': find_routes_page_url})
html = render_to_string('mail/m_found_matched_routes.html', Dict)
mail_sets = get_mail_send_options()
to = [route.owner.email, 'web@syncsystems.net']
subject = _('Мы нашли исполнителя по Вашему объявлению!')
res = admin_send_mail_by_SMTPlib(
mail_sets,
subject=subject,
from_email=mail_sets['sender_email'], to=to,
html_content=html
)
return res
def search_matches(for_routes=None):
log = ''
try:
if not for_routes:
for_routes = Route.objects.filter(
createDT__gte=datetime.now() - timedelta(hours=1),
receive_msg_by_email=True
)
check_fields = [
'type_transport', 'departure_DT', 'arrival_DT', 'from_address_point', 'to_address_point',
'from_place', 'to_place', 'cargo_type', 'weight'
]
for route in for_routes:
kwargs = {}
params = {}
for field_name in check_fields:
field_val = getattr(route, field_name, None)
if field_val:
if type(field_val) == datetime:
params.update({f"{field_name}": f'{field_val.strftime("%d.%m.%Y")} - {field_val.strftime("%d.%m.%Y")}'})
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':
kwargs.update({f"{field_name}__lte": field_val})
else:
kwargs.update({f"{field_name}__gte": field_val})
else:
kwargs.update({field_name: field_val})
params.update({field_name: field_val})
found_routes = Route.objects.exclude(
id=route.id,
).exclude(
owner=route.owner
).exclude(
owner_type=route.owner_type
).filter(
**kwargs
# ).count(
)
if found_routes:
msg = send_mail_found_matches_routes(route, params, found_routes[0].owner_type)
if msg:
log += msg
except Exception as e:
msg = f'<br>\n! search_matches Error = {str(e)}'
log += msg
mail_sets = get_mail_send_options()
techSendMail(mail_sets, log, msg)
return log

View File

@@ -15,6 +15,8 @@ from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CSRF_TRUSTED_ORIGINS = ['https://tripwb.com']
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

View File

@@ -1443,7 +1443,9 @@
.header_logo, .header_btn_mover{
margin-right: 26px;
}
.cookie_block{
width: 100%;
}
.menu_buttons.curtain.left.close.chat{
width: 265px;
}

View File

@@ -2910,4 +2910,44 @@
.handler_curtain_left{
display: none;
}
/*cookie*/
.cookie_block{
background: #000000;
width: 951px;
position: fixed;
bottom: 5px;
z-index: 100000000000000;
box-sizing: border-box;
display: none;
}
.cookie_block.show{
display: block;
}
.txt_cookie{
color: #FFFFFF;
font-size: 14px;
}
.a_cookie{
color: #FFFFFF;
font-size: 14px;
}
.container_content_cookie_block{
display: flex;
justify-content: space-between;
padding: 15px;
}
.cookie_btn{
background: none;
border: 2px solid white;
color: #FFFFFF;
height: 25px;
width: 95px;
cursor: pointer;
}

View File

@@ -58,6 +58,7 @@ function ajax_for_filter (data_d,get_url){
document.querySelector(".container_loader_filters_routes").classList.toggle("show")
}
$.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: '/routes/find_routes/',
type: "POST",

View File

@@ -1,6 +1,6 @@
// $(document).ready(function (){
// middleWareJS()
// })
$(document).ready(function (){
checkStateCookie()
})
// window.onfocus = function () {
// getSocketState()
@@ -151,3 +151,29 @@ function scroll_ev (event,el){
}
}
function checkStateCookie () {
if (!window.document.cookie.includes("allow_cookie=true")){
document.querySelector(".cookie_block").classList.add("show")
}
}
function getCsrfCookie () {
let str = window.document.cookie
str = str.split('; ');
let obj_cookie = {}
for (let i = 0;i < str.length;i++){
let cur = str[i].split('=');
obj_cookie[cur[0]] = cur[1]
}
let csrf = obj_cookie['csrftoken']
return csrf
}
function setCokie () {
let date = new Date();
let days = 182;
date.setTime(+ date + (days * 86400000));
window.document.cookie = "allow_cookie=true" + "; expires=" + date.toGMTString() + "; path=/";
document.querySelector(".cookie_block").classList.remove("show")
return value;
}

View File

@@ -25,6 +25,7 @@ function select_tab_profile (el,url,owner_type=null) {
document.querySelector(".info_profile").innerHTML = '<img src="/static/img/svg/loader.svg" style="height: 30px;position: absolute;top: 47%;left: 45%;"/>'
}
$.ajax({
// headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
headers: { "X-CSRFToken": $('input[name=csrfmiddlewaretoken]').val() },
url: confirm_url,
type: "POST",

View File

@@ -0,0 +1,80 @@
<div style="font-family:Calibri,Candara,Segoe,'Segoe UI',Optima,Arial,sans-serif;
padding:10px; background-color: #F8F8F8;"
>
<div style="line-height:1.0em; width: 660px">
<div style="padding:5px; text-align: center;">
<img src="{{ logo }}" alt="{{ project_name }}" style="margin:0;padding:0;">
</div>
<p style="font-weight:700; font-size:25px; text-align:center;
padding:0; line-height:1em; text-transform: uppercase; color: #ff613a;
margin: auto; max-width: 90%;
">
Здравствуйте, {{ route.owner }}!
</p>
<div style="line-height:1.0em; font-size:18px; margin: 5px 30px;
box-shadow: -1px 4px 10px 0 rgba(198, 199, 203, 0.20), 0 -1px 10px 0 rgba(198, 199, 203, 0.20);
padding: 30px; border-radius: 10px; background-color: #FFF;">
<p>Ранее вы на сайте <a href="{{ domain }}/profile/page/my_routes/"> размещали объявление о поиске {% if search_owner_type == 'mover' %}Перевозчика{% else %}Отправителя{% endif %}</a> и попросили нас уведомить Вас о появлении объявлений, которые соответствуют Вашему критерию.</p>
<p><b>Хорошая новость!</b></p>
<p><b>По заданным критериям поиска мы нашли исполнителя!</b></p>
<p>Чтобы узнать подробности и открыть доступ к контактам, перейдите <a href="{{ find_routes_page_url }}">по этой ссылке и используйте свои учетные данные для входа</a>.
<p>Если у вас возникнут вопросы или вам потребуется помощь, наша служба поддержки всегда готова помочь. Свяжитесь с нами по адресу <a href="mailto:support@tripwb.com">support@tripwb.com</a></p>
<p>
Спасибо за то, что вы с нами!<br>
С уважением,<br>
Команда Trip With Bonus.<br>
</p>
</div>
{% for button in message_buttons %}
<div style="text-align:center;font-weight: 700;">
<a href="{{ button.url }}">
<div style="display:inline-block;text-align:center;font-size:18px;padding:5px 10px;margin:5px;border-radius:2px;background-color:#61aeb6;color:#fff;text-decoration:none;line-height:1.0em;cursor:pointer">
{{ button.caption }}
</div>
</a>
</div>
{% endfor %}
<div style="text-align:center;width: 660px;line-height:1.1em">
<div style="margin: 40px 10px 10px;">
<hr>
{# <nobr><b>Адрес кафе:</b> Минск, ул. Будславская, 2</nobr>#}
{# <br>#}
{# <nobr><b>График работы:</b> пн-вс 12:00 - 24:00</nobr>#}
{# <br>#}
{# <nobr><b>Телефоны кафе:</b> +375 44 77 321 77</nobr>#}
</div>
</div>
<div style="text-align: center;margin-top:5px">
{# <a href="https://baldenini.by/event/dostavka-edy" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О ДОСТАВКЕ#}
{# </div>#}
{# </a>#}
{# <a href="https://baldenini.by/page/baldenini-cafe-o-nas" style="text-decoration: none;">#}
{# <div style="color: #311A12;#}
{# padding: 10px;#}
{# margin: 5px 10px 0 10px;#}
{# border: 2px solid #311A12;#}
{# border-radius: 5px;#}
{# font-size: 20px;#}
{# display: inline-block;#}
{# font-weight: 700;#}
{# text-transform: uppercase;">О BALDENINI CAFE#}
{# </div>#}
{# </a>#}
</div>
</div>
</div>

View File

@@ -28,7 +28,7 @@
<script>
{#var user_id = {{ user.id }}#}
ws_url = `ws://{% get_ws_address %}/ws/socket-server/?user_id={{ user.id }}`;
ws_url = `wss://{% get_ws_address %}/ws/socket-server/?user_id={{ user.id }}`;
var chatSocket;
init_ws()
const beep = new Audio('/static/sounds/beep_2.mp3')
@@ -59,6 +59,14 @@
</head>
<body{% if page_type == 'routes' %} onscroll="scroll_ev(event,this)"{% endif %}>
<div class="cookie_block">
<div class="container_content_cookie_block">
<div class="txt_cookie">Сайт использует файлы cookie. Просматривая этот сайт, Вы соглашаетесь
<a class="a_cookie" href="#">с условиями использования cookie-файлов</a>
</div>
<button class="cookie_btn" onclick="setCokie()">Понятно</button>
</div>
</div>
{% if page_type != 'routes' %}
<script>