Files
smartsoltech_site/smartsoltech/web/views.py
trevor f17c6b3a1a main funtions are ready
issue: ServiceRequest creates when QR code scanned
2024-10-14 05:24:48 +09:00

296 lines
12 KiB
Python

from django.shortcuts import render, get_object_or_404, redirect
from .models import Service, Project, Client, BlogPost, Review, Order, ServiceRequest
from django.db.models import Avg
from comunication.models import TelegramSettings
import qrcode
import os
from django.conf import settings
import uuid
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from django.http import JsonResponse
from django.utils.crypto import get_random_string # Импорт get_random_string
from django.contrib.auth.models import User
from decouple import config
from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from comunication.telegram_bot import TelegramBot
import hmac
import hashlib
import json
from django.views.decorators.csrf import csrf_exempt
# sens
try:
bot = TelegramBot()
except Exception as e:
print (e)
def home(request):
services = Service.objects.all()
return render(request, 'web/home.html', {'services': services})
def service_detail(request, pk):
service = get_object_or_404(Service, pk=pk)
projects_in_category = Project.objects.filter(category=service.category)
average_rating = service.reviews.aggregate(Avg('rating'))['rating__avg'] or 0
total_reviews = service.reviews.count()
reviews = service.reviews.all()
return render(request, 'web/service_detail.html', {
'service': service,
'projects_in_category': projects_in_category,
'average_rating': average_rating,
'total_reviews': total_reviews,
'reviews': reviews,
})
def project_detail(request, pk):
project = get_object_or_404(Project, pk=pk)
return render(request, 'web/project_detail.html', {'project': project})
def client_detail(request, pk):
client = get_object_or_404(Client, pk=pk)
return render(request, 'web/client_detail.html', {'client': client})
def blog_post_detail(request, pk):
blog_post = get_object_or_404(BlogPost, pk=pk)
return render(request, 'web/blog_post_detail.html', {'blog_post': blog_post})
def services_view(request):
services = Service.objects.all()
return render(request, 'web/services.html', {'services': services})
def about_view(request):
return render(request, 'web/about.html')
def create_service_request(request, service_id):
service = get_object_or_404(Service, pk=service_id)
if request.method == 'POST':
client_name = request.POST.get('client_name')
client_email = request.POST.get('client_email')
client_phone = request.POST.get('client_phone')
description = request.POST.get('description') # New description field
chat_id = request.POST.get('chat_id')
token = uuid.uuid4().hex
# Check for existing service request
service_request = ServiceRequest.objects.filter(client_email=client_email, client_phone=client_phone).first()
if not service_request:
# Create a new service request
service_request = ServiceRequest.objects.create(
service=service,
client_name=client_name,
client_email=client_email,
client_phone=client_phone,
chat_id=chat_id,
token=token
)
# Generate user credentials
username = f"{client_email.split('@')[0]}_{get_random_string(5)}"
password = get_random_string(8)
# Create a new user
user = User.objects.create_user(username=username, password=password)
user.first_name = client_name.split()[0] if client_name else ""
user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else ""
user.email = client_email
user.save()
# Create or get client
client, created = Client.objects.get_or_create(
email=client_email,
defaults={
'first_name': user.first_name,
'last_name': user.last_name,
'phone_number': client_phone,
}
)
# Create an order linked to the service request and client
order = Order.objects.create(
service=service,
client=client,
message=description,
status="pending"
)
# Send credentials via Telegram
if chat_id:
bot.send_telegram_message(client.id, service_request.id, "Ваши данные для входа на сайт.", order.id)
else:
# If service request exists, update the chat_id
service_request.chat_id = chat_id
service_request.save()
return redirect(reverse('order_detail', args=[order.pk]))
def generate_qr_code(request, service_id):
service = get_object_or_404(Service, pk=service_id)
telegram_settings = get_object_or_404(TelegramSettings, pk=1)
token = uuid.uuid4().hex
# Создание новой заявки на услугу
service_request = ServiceRequest.objects.create(
service=service,
client_name='',
client_email='',
client_phone='',
token=token
)
# Генерация ссылки для регистрации в Telegram
registration_link = (f'https://t.me/{telegram_settings.bot_name}?start=request_{service_request.id}_token_{urlsafe_base64_encode(force_bytes(token))}'
)
# Генерация QR-кода
qr = qrcode.make(registration_link)
qr_code_dir = os.path.join(settings.STATICFILES_DIRS[0], 'qr_codes')
qr_code_path = os.path.join(qr_code_dir, f"request_{service_request.id}.png")
external_qr_link = f'static/qr_codes/request_{service_request.id}.png'
if not os.path.exists(qr_code_dir):
os.makedirs(qr_code_dir)
qr.save(qr_code_path)
return JsonResponse({
'registration_link': registration_link,
'qr_code_url': f"/{external_qr_link}",
'service_request_id': service_request.id
})
def complete_registration(request, request_id):
# Завершение регистрации по идентификатору заявки
service_request = get_object_or_404(ServiceRequest, pk=request_id)
if request.method == 'POST':
client_name = request.POST.get('client_name', service_request.client_name)
client_email = request.POST.get('client_email', service_request.client_email)
client_phone = request.POST.get('client_phone', service_request.client_phone)
chat_id = request.POST.get('chat_id', service_request.chat_id)
# Обновляем данные заявки
service_request.client_name = client_name
service_request.client_email = client_email
service_request.client_phone = client_phone
service_request.chat_id = chat_id
service_request.save()
return redirect('home')
return render(request, 'web/complete_registration.html', {'service_request': service_request})
def request_status(request, service_id):
# Проверяем статус заявки на услугу
service_request = get_object_or_404(ServiceRequest, pk=service_id)
is_verified = service_request.client_name != '' and service_request.chat_id != ''
return JsonResponse({
'is_verified': is_verified,
'client_name': service_request.client_name,
'client_chat_id' : service_request.chat_id,
})
def complete_registration_basic(request):
# Базовая регистрация без идентификатора заявки
if request.method == 'POST':
client_name = request.POST.get('client_name')
client_email = request.POST.get('client_email')
client_phone = request.POST.get('client_phone')
# # Создаем новую запись заявки
# service_request = ServiceRequest.objects.create(
# client_name=client_name,
# client_email=client_email,
# client_phone=client_phone
# )
return redirect('home')
return render(request, 'web/complete_registration_basic.html')
def check_service_request_data(request, token=None, request_id=None):
# Проверка наличия данных в таблице ServiceRequest по токену или номеру заявки
service_request = None
if token:
try:
service_request = ServiceRequest.objects.get(token=token)
except ServiceRequest.DoesNotExist:
service_request = None
elif request_id:
try:
service_request = ServiceRequest.objects.get(id=request_id)
except ServiceRequest.DoesNotExist:
service_request = None
if service_request:
return JsonResponse({
'exists': True,
'client_name': service_request.client_name,
'client_email': service_request.client_email,
'client_phone': service_request.client_phone,
'chat_id': service_request.chat_id
})
else:
return JsonResponse({'exists': False})
def order_detail(request, pk):
order = get_object_or_404(Order, pk=pk)
return render(request, 'web/order_detail.html', {'order': order})
@login_required
def client_orders(request):
client = request.user.client_profile
orders = client.related_orders.all()
return render(request, 'web/client_orders.html', {'orders': orders})
def generate_secure_token(service_request_id, secret_key):
"""Генерация безопасного токена для подтверждения подлинности запроса."""
data = f'{service_request_id}:{secret_key}'
return hmac.new(secret_key.encode(), data.encode(), hashlib.sha256).hexdigest()
@csrf_exempt
def send_telegram_notification(request):
if request.method == 'POST':
try:
data = json.loads(request.body)
service_request_id = data.get('service_request_id')
provided_token = data.get('token')
# Проверка корректности переданных данных
if not service_request_id or not provided_token:
return JsonResponse({'error': 'Недостаточно данных для подтверждения'}, status=400)
# Получение заявки
service_request = ServiceRequest.objects.filter(id=service_request_id).first()
if not service_request:
return JsonResponse({'error': 'Заявка не найдена'}, status=404)
# Генерация токена и сравнение
secret_key = settings.SECRET_KEY # Используем секретный ключ из настроек
expected_token = generate_secure_token(service_request_id, secret_key)
if not hmac.compare_digest(provided_token, expected_token):
return JsonResponse({'error': 'Неверный токен. Доступ запрещен.'}, status=403)
# Отправка сообщения в Telegram
chat_id = service_request.chat_id
if not chat_id:
return JsonResponse({'error': 'Нет chat_id для отправки сообщения'}, status=400)
message = (
f"Здравствуйте, {service_request.client_name}!\n"
f"Ваша заявка на услугу '{service_request.service.name}' успешно зарегистрирована."
)
bot.send_telegram_message(chat_id=chat_id, message=message)
return JsonResponse({'status': 'Уведомление успешно отправлено в Telegram'})
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405)