diff --git a/smartsoltech/comunication/telegram_bot.py b/smartsoltech/comunication/telegram_bot.py index d67cbc8..80914e2 100644 --- a/smartsoltech/comunication/telegram_bot.py +++ b/smartsoltech/comunication/telegram_bot.py @@ -1,162 +1,40 @@ -# import telebot -# from decouple import config -# from django.shortcuts import get_object_or_404 -# from web.models import Client, ServiceRequest, Order -# from comunication.models import TelegramSettings -# import re -# import base64 -# import logging - -# class TelegramBot: -# def __init__(self): -# # Get bot settings from the database -# bot_settings = TelegramSettings.objects.first() -# if bot_settings: -# TELEGRAM_BOT_TOKEN = bot_settings.bot_token -# self.bot = telebot.TeleBot(TELEGRAM_BOT_TOKEN) -# else: -# raise Exception("Telegram bot settings not found") - -# def start_bot_polling(self): -# @self.bot.message_handler(commands=['start']) -# def send_welcome(message): -# # Проверяем, содержатся ли параметры в команде /start -# match = re.match(r'/start request_(\d+)_token_(.*)', message.text) -# if match: -# self.handle_confirm_command(message, match) -# elif message.text.strip() == '/start': -# self.bot.reply_to(message, "Ошибка: Некорректная команда. Пожалуйста, используйте ссылку, предоставленную на сайте для регистрации.") -# else: -# self.bot.reply_to(message, "Здравствуйте! Чем я могу помочь? Вы можете задать вопросы о статусе заявки или заказе.") - -# @self.bot.message_handler(func=lambda message: 'статус заявки' in message.text.lower()) -# def handle_service_request_status(message): -# chat_id = message.chat.id -# client = Client.objects.filter(chat_id=chat_id).first() -# if client: -# service_requests = ServiceRequest.objects.filter(client_email=client.email) -# if service_requests.exists(): -# response = "Ваши заявки:\n" -# for req in service_requests: -# response += f"Номер заявки: {req.id}, Услуга: {req.service.name}, Дата создания: {req.created_at.strftime('%d-%m-%Y')}\n" -# else: -# response = "У вас нет активных заявок." -# else: -# response = "Клиент не найден. Пожалуйста, зарегистрируйтесь." -# self.bot.reply_to(message, response) - -# @self.bot.message_handler(func=lambda message: 'статус заказа' in message.text.lower()) -# def handle_order_status(message): -# chat_id = message.chat.id -# client = Client.objects.filter(chat_id=chat_id).first() -# if client: -# orders = Order.objects.filter(client=client) -# if orders.exists(): -# response = "Ваши заказы:\n" -# for order in orders: -# response += f"Номер заказа: {order.id}, Услуга: {order.service.name}, Статус: {order.get_status_display()}\n" -# else: -# response = "У вас нет активных заказов." -# else: -# response = "Клиент не найден. Пожалуйста, зарегистрируйтесь." -# self.bot.reply_to(message, response) - -# self.bot.polling(non_stop=True) - -# def handle_confirm_command(self, message, match=None): -# chat_id = message.chat.id -# if not match: -# match = re.match(r'/start request_(\d+)_token_(.*)', message.text) -# if match: -# request_id = match.group(1) -# encoded_token = match.group(2) - -# # Декодируем токен из base64 -# try: -# token = base64.urlsafe_b64decode(encoded_token + '==').decode('utf-8') -# logging.info(f"Декодированный токен: {token}") -# except Exception as e: -# logging.error(f"Ошибка при декодировании токена: {e}") -# self.bot.send_message(chat_id, "Ошибка: Некорректный токен. Пожалуйста, повторите попытку позже.") -# return - -# # Получаем заявку по ID и токену -# service_request = ServiceRequest.objects.filter(id=request_id, token=token).first() -# if service_request: -# # Обновляем chat_id клиента -# service_request.chat_id = chat_id -# service_request.client_name = message.from_user.first_name -# service_request.save() - -# response_message = ( -# f"Здравствуйте, {message.from_user.first_name}!\n" -# f"Ваша заявка на услугу успешно зарегистрирована. " -# f"Пожалуйста, вернитесь на сайт для продолжения оформления." -# ) -# else: -# response_message = "Ошибка: Неверная заявка или токен. Пожалуйста, проверьте ссылку." - -# self.bot.send_message(chat_id, response_message) -# else: -# response_message = "Ошибка: Некорректная команда. Пожалуйста, используйте ссылку, предоставленную на сайте для регистрации." -# self.bot.send_message(chat_id, response_message) - -# def send_telegram_message(self, client_id, service_request_id, custom_message, order_id=None): -# # Get the client and service request from the database -# client = get_object_or_404(Client, pk=client_id) -# service_request = get_object_or_404(ServiceRequest, pk=service_request_id) -# chat_id = client.chat_id - -# # Build the message content -# message = f"Здравствуйте, {client.first_name} {client.last_name}!\n" -# message += custom_message - -# if order_id: -# order = get_object_or_404(Order, pk=order_id) -# message += f"\n\nДетали заказа:\nУслуга: {order.service.name}\nСтатус: {order.get_status_display()}\n" - -# # Add service request details -# message += f"\nНомер заявки: {service_request.id}\nДата создания заявки: {service_request.created_at.strftime('%d-%m-%Y')}\n" - -# # Send the message using the bot -# try: -# self.bot.send_message(chat_id, message) -# except Exception as e: -# logging.error(f"Ошибка при отправке сообщения в Telegram: {e}") - - -import telebot -from telebot import types -from decouple import config -from django.shortcuts import get_object_or_404 -from web.models import Client, ServiceRequest, Order -from comunication.models import TelegramSettings -import re -import base64 import logging +import json +import requests +import os +import base64 +import re +from comunication.models import TelegramSettings +from web.models import ServiceRequest, Order, Project, Client, User +import telebot +from django.shortcuts import get_object_or_404 +from django.utils.crypto import get_random_string class TelegramBot: def __init__(self): - # Get bot settings from the database + # Получение настроек бота из базы данных bot_settings = TelegramSettings.objects.first() if bot_settings: TELEGRAM_BOT_TOKEN = bot_settings.bot_token self.bot = telebot.TeleBot(TELEGRAM_BOT_TOKEN) + logging.info("[TelegramBot] Бот инициализирован с токеном.") else: raise Exception("Telegram bot settings not found") def start_bot_polling(self): + logging.info("[TelegramBot] Бот начал работу в режиме polling.") + @self.bot.message_handler(commands=['start']) def send_welcome(message): # Проверяем, содержатся ли параметры в команде /start match = re.match(r'/start request_(\d+)_token_(.*)', message.text) + logging.info(f"[TelegramBot] Получена команда /start: {message.text}") + if match: self.handle_confirm_command(message, match) elif message.text.strip() == '/start': - kbd = types.InlineKeyboardMarkup() - url_btn = types.InlineKeyboardButton('Перейти на сайт', url=config("URL")) - kbd.add(url_btn) - self.bot.reply_to(message, "Здравствуйте! Данный бот предназначен для информирования клиентов SmartSolTech и регистрации на сайте. Пройдите на сайт для получения информации.", reply_markup = kbd) + # Ответ на просто команду /start без параметров + self.bot.reply_to(message, "Здравствуйте! Пожалуйста, используйте команду /start с корректными параметрами для подтверждения регистрации.") else: self.bot.reply_to(message, "Здравствуйте! Пожалуйста, используйте команду /start с корректными параметрами для подтверждения регистрации.") @@ -165,14 +43,17 @@ class TelegramBot: chat_id = message.chat.id client = Client.objects.filter(chat_id=chat_id).first() if client: - service_requests = ServiceRequest.objects.filter(chat_id=client.chat_id) + service_requests = ServiceRequest.objects.filter(client=client) if service_requests.exists(): response = "Ваши заявки:\n" for req in service_requests: - response += f"Номер заявки: {req.id}\n" \ - f"Услуга: {req.service.name}\n" \ - f"Дата создания: {req.created_at.strftime('%Y-%m-%d')}\n" \ - f"UID заявки: {req.token}\n" + response += ( + f"Номер заявки: {req.id}\n" + f"Услуга: {req.service.name}\n" + f"Дата создания: {req.created_at.strftime('%Y-%m-%d')}\n" + f"UID заявки: {req.token}\n" + f"Подтверждена: {'Да' if req.is_verified else 'Нет'}\n\n" + ) else: response = "У вас нет активных заявок." else: @@ -188,19 +69,52 @@ class TelegramBot: if orders.exists(): response = "Ваши заказы:\n" for order in orders: - response += f"Номер заказа: {order.id}, Услуга: {order.service.name}, Статус: {order.get_status_display()}\n" + response += ( + f"Номер заказа: {order.id}\n" + f"Услуга: {order.service.name}\n" + f"Статус: {order.get_status_display()}\n\n" + ) else: response = "У вас нет активных заказов." else: response = "Клиент не найден. Пожалуйста, зарегистрируйтесь." self.bot.reply_to(message, response) - self.bot.polling(non_stop=True) + @self.bot.message_handler(func=lambda message: 'статус проекта' in message.text.lower()) + def handle_project_status(message): + chat_id = message.chat.id + client = Client.objects.filter(chat_id=chat_id).first() + if client: + projects = Project.objects.filter(order__client=client) + if projects.exists(): + response = "Ваши проекты:\n" + for project in projects: + response += ( + f"Номер проекта: {project.id}\n" + f"Название проекта: {project.name}\n" + f"Статус: {project.get_status_display()}\n" + f"Дата завершения: {project.completion_date.strftime('%Y-%m-%d') if project.completion_date else 'В процессе'}\n\n" + ) + else: + response = "У вас нет активных проектов." + else: + response = "Клиент не найден. Пожалуйста, зарегистрируйтесь." + self.bot.reply_to(message, response) + + + # Запуск бота + try: + self.bot.polling(non_stop=True) + except Exception as e: + logging.error(f"[TelegramBot] Ошибка при запуске polling: {e}") def handle_confirm_command(self, message, match=None): chat_id = message.chat.id + logging.info(f"[TelegramBot] Получено сообщение для подтверждения: {message.text}") + if not match: match = re.match(r'/start request_(\d+)_token_(.*)', message.text) + if match: request_id = match.group(1) encoded_token = match.group(2) @@ -208,61 +122,88 @@ class TelegramBot: # Декодируем токен try: token = base64.urlsafe_b64decode(encoded_token + '==').decode('utf-8') + logging.info(f"[TelegramBot] Декодированный токен: {token}") except Exception as e: + logging.error(f"[TelegramBot] Ошибка при декодировании токена: {e}") self.bot.send_message(chat_id, "Ошибка: Некорректный токен. Пожалуйста, повторите попытку позже.") return # Получаем заявку - service_request = ServiceRequest.objects.filter(id=request_id, token=token).first() - if service_request: - # Обновляем chat_id клиента - service_request.chat_id = chat_id - service_request.client_name = message.from_user.first_name - service_request.save() + try: + service_request = ServiceRequest.objects.get(id=request_id, token=token) + logging.info(f"[TelegramBot] Заявка найдена: {service_request}") + except ServiceRequest.DoesNotExist: + logging.error(f"[TelegramBot] Заявка с id {request_id} и токеном {token} не найдена.") + self.bot.send_message(chat_id, "Ошибка: Неверная заявка или токен. Пожалуйста, проверьте ссылку.") + return + + # Если заявка найдена, обновляем и подтверждаем клиента + if service_request: + service_request.chat_id = chat_id + service_request.is_verified = True # Обновляем статус на подтвержденный + service_request.save() + logging.info(f"[TelegramBot] Заявка {service_request.id} подтверждена и обновлена.") + + # Обновляем или создаем клиента, связанного с заявкой + client = service_request.client + + # Проверяем, существует ли связанный пользователь, если нет — создаем его + if not client.user: + user, created = User.objects.get_or_create( + email=client.email, + defaults={ + 'username': f"{client.email.split('@')[0]}_{get_random_string(5)}", + 'first_name': message.from_user.first_name, + 'last_name': message.from_user.last_name if message.from_user.last_name else '' + } + ) + + if not created: + # Если пользователь уже существовал, обновляем его данные + user.first_name = message.from_user.first_name + if message.from_user.last_name: + user.last_name = message.from_user.last_name + user.save() + logging.info(f"[TelegramBot] Обновлен пользователь {user.username} с данными из Телеграм.") + + # Связываем клиента с пользователем + client.user = user + client.save() - # Отправляем данные обратно на сервер для создания заявки - data = { - "service_request_id": request_id, - "client_name": message.from_user.first_name, - "client_chat_id": chat_id - } - response = requests.post('http://localhost:8000/service/send_telegram_notification/', json=data) - if response.status_code == 200: - self.bot.send_message(chat_id, "Ваш аккаунт успешно подтвержден! Вернитесь на сайт для продолжения.") else: - self.bot.send_message(chat_id, "Ошибка при подтверждении. Пожалуйста, повторите попытку позже.") + # Обновляем данные существующего пользователя + user = client.user + user.first_name = message.from_user.first_name + if message.from_user.last_name: + user.last_name = message.from_user.last_name + user.save() + logging.info(f"[TelegramBot] Пользователь {user.username} обновлен с данными из Телеграм.") + + # Обновляем chat_id клиента + client.chat_id = chat_id + client.save() + logging.info(f"[TelegramBot] Клиент {client.id} обновлен с chat_id {chat_id}") + + # Отправляем сообщение пользователю в Telegram с подтверждением и информацией о заявке + confirmation_message = ( + f"Здравствуйте, {client.first_name}!\n\n" + f"Ваш аккаунт успешно подтвержден! 🎉\n\n" + f"Детали вашей заявки:\n" + f"Номер заявки: {service_request.id}\n" + f"Услуга: {service_request.service.name}\n" + f"Статус заявки: {'Подтверждена' if service_request.is_verified else 'Не подтверждена'}\n" + f"Дата создания: {service_request.created_at.strftime('%Y-%m-%d %H:%M:%S')}\n" + f"Спасибо, что выбрали наши услуги! Если у вас возникнут вопросы, вы всегда можете обратиться к нам." + ) + self.bot.send_message(chat_id, confirmation_message) + + # Вместо дополнительного POST-запроса — сообщаем о подтверждении через сообщение + self.bot.send_message(chat_id, "Ваш аккаунт успешно подтвержден на сервере! Продолжайте на сайте.") + else: self.bot.send_message(chat_id, "Ошибка: Неверная заявка или токен. Пожалуйста, проверьте ссылку.") - - self.bot.send_message(chat_id, response_message) else: response_message = "Ошибка: Некорректная команда. Пожалуйста, используйте ссылку, предоставленную на сайте для регистрации." self.bot.send_message(chat_id, response_message) - def send_telegram_message(self, client_id, service_request_id, custom_message, order_id=None): - # Get the client and service request from the database - client = get_object_or_404(Client, pk=client_id) - service_request = get_object_or_404(ServiceRequest, pk=service_request_id) - chat_id = client.chat_id - # Build the message content - message = f"Здравствуйте, {client.first_name} {client.last_name}!\n" - message += custom_message - - if order_id: - order = get_object_or_404(Order, pk=order_id) - message += f"\n\nДетали заказа:\nУслуга: {order.service.name}\nСтатус: {order.get_status_display()}\n" - - # Add service request details - message += f"\nНомер заявки: {service_request.id}\nДата создания заявки: {service_request.created_at.strftime('%d-%m-%Y')}\n" - - # Send the message using the bot - try: - self.bot.send_message(chat_id, message) - except Exception as e: - logging.error(f"Ошибка при отправке сообщения в Telegram: {e}") - -# Example usage: -# bot = TelegramBot() -# bot.start_bot_polling() -# bot.send_telegram_message(client_id=1, service_request_id=1, custom_message="Ваши данные для входа на сайт.") \ No newline at end of file diff --git a/smartsoltech/media/static/img/customer/JD-26-512_SKOAvnB.jpg b/smartsoltech/media/static/img/customer/JD-26-512_SKOAvnB.jpg new file mode 100644 index 0000000..887a592 Binary files /dev/null and b/smartsoltech/media/static/img/customer/JD-26-512_SKOAvnB.jpg differ diff --git a/smartsoltech/static/assets/js/get-csrf-token.js b/smartsoltech/static/assets/js/get-csrf-token.js new file mode 100644 index 0000000..ba7123b --- /dev/null +++ b/smartsoltech/static/assets/js/get-csrf-token.js @@ -0,0 +1,18 @@ +// Функция для получения CSRF токена из куков +function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== '') { + const cookies = document.cookie.split(';'); + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim(); + if (cookie.substring(0, name.length + 1) === (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} + +// Инициализация переменной csrftoken, которая будет доступна глобально +const csrftoken = getCookie('csrftoken'); \ No newline at end of file diff --git a/smartsoltech/static/assets/js/modal-init.js b/smartsoltech/static/assets/js/modal-init.js index 9da3b06..fcb6ea4 100644 --- a/smartsoltech/static/assets/js/modal-init.js +++ b/smartsoltech/static/assets/js/modal-init.js @@ -1,110 +1,49 @@ document.addEventListener("DOMContentLoaded", function () { + // Работа с модальным окном заявки var modalElement = document.getElementById('orderModal'); if (modalElement) { var modal = new bootstrap.Modal(modalElement); - + // Инициализация модального окна - modalElement.addEventListener('show.bs.modal', function (event) { + modalElement.addEventListener('show.bs.modal', function () { console.log("Модальное окно открыто"); }); - modalElement.addEventListener('hide.bs.modal', function (event) { + modalElement.addEventListener('hide.bs.modal', function () { console.log("Модальное окно закрыто"); }); } -}); -document.addEventListener('DOMContentLoaded', function () { - const generateQrButton = document.getElementById('generateQrButton'); + // Открытие модального окна для заявки на услугу + const openModalBtn = document.getElementById('openModalBtn'); + const serviceModal = document.getElementById('serviceModal'); - if (generateQrButton) { - generateQrButton.addEventListener('click', function () { - const clientEmail = document.getElementById('clientEmail').value; - const clientPhone = document.getElementById('clientPhone').value; - const clientName = document.getElementById('clientName').value; - const description = document.getElementById('description').value; - const serviceId = generateQrButton.getAttribute('data-service-id'); + if (openModalBtn && serviceModal) { + openModalBtn.addEventListener('click', function (event) { + event.preventDefault(); + const serviceId = openModalBtn.getAttribute('data-service-id'); + console.log("Service ID при открытии модального окна:", serviceId); - // Проверка заполненности полей - if (!clientEmail || !clientPhone || !clientName || !description || !serviceId) { - alert('Все поля должны быть заполнены.'); + if (!serviceId) { + alert("Идентификатор услуги не найден. Обновите страницу и попробуйте снова."); return; } - // Получение CSRF токена из cookies - function getCookie(name) { - let cookieValue = null; - if (document.cookie && document.cookie !== '') { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i].trim(); - if (cookie.substring(0, name.length + 1) === (name + '=')) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; - } + generateQrButton.dataset.serviceId = serviceId; - const csrftoken = getCookie('csrftoken'); - - // Отправка POST запроса на создание заявки - fetch('/service/create_request/', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRFToken': csrftoken - }, - body: JSON.stringify({ - client_email: clientEmail, - client_phone: clientPhone, - client_name: clientName, - service_id: serviceId, - description: description - }) - }) - .then(response => { - if (!response.ok) { - throw new Error('Ошибка при создании заявки'); - } - return response.json(); - }) - .then(data => { - if (data.status === 'success') { - alert(data.message); - } else if (data.status === 'existing_request') { - alert(data.message); - } else { - alert('Неизвестная ошибка. Пожалуйста, попробуйте снова.'); - } - }) - .catch(error => { - console.error('Ошибка при создании заявки:', error); - }); + serviceModal.classList.add('show'); + serviceModal.style.display = 'block'; }); } -}); -function checkVerificationStatus(serviceRequestId, interval) { - fetch(`/service/request_status/${serviceRequestId}/`) - .then(response => { - if (!response.ok) { - throw new Error('Ошибка при проверке статуса заявки'); + document.querySelectorAll('.close').forEach(closeBtn => { + closeBtn.addEventListener('click', function () { + if (serviceModal) { + serviceModal.classList.remove('show'); + setTimeout(() => { + serviceModal.style.display = 'none'; + }, 500); } - return response.json(); - }) - .then(data => { - if (data.is_verified) { - // Закрываем форму и показываем окно подтверждения - document.getElementById('serviceModal').style.display = 'none'; - document.getElementById('confirmationModal').style.display = 'block'; - - // Останавливаем интервал проверки статуса - clearInterval(interval); - } - }) - .catch(error => { - console.error('Ошибка при проверке статуса заявки:', error); }); -} \ No newline at end of file + }); +}); diff --git a/smartsoltech/static/assets/js/service_request.js b/smartsoltech/static/assets/js/service_request.js new file mode 100644 index 0000000..4d9a22c --- /dev/null +++ b/smartsoltech/static/assets/js/service_request.js @@ -0,0 +1,116 @@ +// service-request.js + +document.addEventListener("DOMContentLoaded", function () { + // Открытие модального окна + const openModalBtn = document.getElementById('openModalBtn'); + const serviceModal = document.getElementById('serviceModal'); + const generateQrButton = document.getElementById('generateQrButton'); + + if (openModalBtn && serviceModal) { + openModalBtn.addEventListener('click', function (event) { + event.preventDefault(); + // Логирование значения serviceId при открытии модального окна + const serviceId = openModalBtn.getAttribute('data-service-id'); + console.log("Service ID при открытии модального окна:", serviceId); + + // Проверяем, если serviceId отсутствует + if (!serviceId) { + alert("Идентификатор услуги не найден. Обновите страницу и попробуйте снова."); + return; + } + + // Сохраняем serviceId для дальнейшего использования + generateQrButton.dataset.serviceId = serviceId; + + // Показываем модальное окно + serviceModal.classList.add('show'); + serviceModal.style.display = 'block'; + }); + } else { + console.error('Не удалось найти элемент с id openModalBtn или serviceModal.'); + } + + // Закрытие модального окна + document.querySelectorAll('.close').forEach(closeBtn => { + closeBtn.addEventListener('click', function () { + if (serviceModal) { + serviceModal.classList.remove('show'); + setTimeout(() => { + serviceModal.style.display = 'none'; + }, 500); + } + }); + }); + + // Обработчик кнопки "Создать заявку" + if (generateQrButton) { + generateQrButton.addEventListener('click', function () { + // Получение значений полей + const clientEmail = document.getElementById('clientEmail').value.trim(); + const clientPhone = document.getElementById('clientPhone').value.trim(); + const clientName = document.getElementById('clientName').value.trim(); + const description = document.getElementById('description').value.trim(); + + // Получаем serviceId из кнопки открытия модального окна + const serviceId = generateQrButton.dataset.serviceId; + + // Логируем для проверки значения serviceId перед отправкой + console.log("Service ID перед отправкой запроса:", serviceId); + + // Проверка заполненности полей + if (!clientEmail || !clientPhone || !clientName || !description || !serviceId) { + let errorMessage = 'Пожалуйста, заполните все поля формы перед продолжением.\n'; + if (!serviceId) { + errorMessage += 'Идентификатор услуги не найден. Обновите страницу и попробуйте снова.\n'; + } + alert(errorMessage); + return; + } + + // Отправка POST запроса на создание заявки + fetch(`/service/generate_qr_code/${serviceId}/`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken // Используем глобально инициализированный CSRF токен + }, + body: JSON.stringify({ + client_email: clientEmail, + client_phone: clientPhone, + client_name: clientName, + description: description + }) + }) + .then(response => { + if (!response.ok) { + throw new Error('Ошибка при создании заявки'); + } + return response.json(); + }) + .then(data => { + if (data.qr_code_url) { + // Обновляем src изображения QR-кода и показываем его + const qrCodeImg = document.getElementById('qrCodeImg'); + if (qrCodeImg) { + qrCodeImg.src = data.qr_code_url; + qrCodeImg.style.display = 'block'; + } + + // Начинаем проверку статуса заявки + const interval = setInterval(() => { + checkVerificationStatus(data.service_request_id, interval); + }, 5000); + } else if (data.status === 'existing_request') { + alert(data.message); + } else { + alert('Неизвестная ошибка. Пожалуйста, попробуйте снова.'); + } + }) + .catch(error => { + console.error('Ошибка при создании заявки:', error); + }); + }); + } else { + console.error('Не удалось найти элемент с id generateQrButton.'); + } +}); diff --git a/smartsoltech/static/assets/js/verification_status.js b/smartsoltech/static/assets/js/verification_status.js new file mode 100644 index 0000000..e973751 --- /dev/null +++ b/smartsoltech/static/assets/js/verification_status.js @@ -0,0 +1,37 @@ +// verification-status.js + +function checkVerificationStatus(serviceRequestId, interval) { + console.log(`Проверка статуса для заявки с ID: ${serviceRequestId}`); // Лог для проверки + + fetch(`/service/request_status/${serviceRequestId}/`) + .then(response => { + if (!response.ok) { + throw new Error('Ошибка при проверке статуса заявки'); + } + return response.json(); + }) + .then(data => { + if (data.is_verified) { + // Закрываем форму и показываем окно подтверждения + const serviceModal = document.getElementById('serviceModal'); + const confirmationModal = document.getElementById('confirmationModal'); + + if (serviceModal) { + serviceModal.style.display = 'none'; + } + + if (confirmationModal) { + confirmationModal.style.display = 'block'; + } + + // Останавливаем интервал проверки статуса + clearInterval(interval); + } + }) + .catch(error => { + console.error('Ошибка при проверке статуса заявки:', error); + }); +} + +// Делаем функцию доступной глобально +window.checkVerificationStatus = checkVerificationStatus; diff --git a/smartsoltech/static/qr_codes/request_347.png b/smartsoltech/static/qr_codes/request_347.png new file mode 100644 index 0000000..20274e5 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_347.png differ diff --git a/smartsoltech/static/qr_codes/request_348.png b/smartsoltech/static/qr_codes/request_348.png new file mode 100644 index 0000000..660b3b6 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_348.png differ diff --git a/smartsoltech/static/qr_codes/request_349.png b/smartsoltech/static/qr_codes/request_349.png new file mode 100644 index 0000000..70caaae Binary files /dev/null and b/smartsoltech/static/qr_codes/request_349.png differ diff --git a/smartsoltech/static/qr_codes/request_350.png b/smartsoltech/static/qr_codes/request_350.png new file mode 100644 index 0000000..9a23111 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_350.png differ diff --git a/smartsoltech/static/qr_codes/request_351.png b/smartsoltech/static/qr_codes/request_351.png new file mode 100644 index 0000000..7fc93fb Binary files /dev/null and b/smartsoltech/static/qr_codes/request_351.png differ diff --git a/smartsoltech/static/qr_codes/request_352.png b/smartsoltech/static/qr_codes/request_352.png new file mode 100644 index 0000000..ca74a9b Binary files /dev/null and b/smartsoltech/static/qr_codes/request_352.png differ diff --git a/smartsoltech/static/qr_codes/request_353.png b/smartsoltech/static/qr_codes/request_353.png new file mode 100644 index 0000000..7a091c8 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_353.png differ diff --git a/smartsoltech/static/qr_codes/request_354.png b/smartsoltech/static/qr_codes/request_354.png new file mode 100644 index 0000000..2a26ed3 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_354.png differ diff --git a/smartsoltech/static/qr_codes/request_355.png b/smartsoltech/static/qr_codes/request_355.png new file mode 100644 index 0000000..42c8e11 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_355.png differ diff --git a/smartsoltech/static/qr_codes/request_356.png b/smartsoltech/static/qr_codes/request_356.png new file mode 100644 index 0000000..8130d2b Binary files /dev/null and b/smartsoltech/static/qr_codes/request_356.png differ diff --git a/smartsoltech/static/qr_codes/request_357.png b/smartsoltech/static/qr_codes/request_357.png new file mode 100644 index 0000000..7366983 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_357.png differ diff --git a/smartsoltech/static/qr_codes/request_358.png b/smartsoltech/static/qr_codes/request_358.png new file mode 100644 index 0000000..78edf7f Binary files /dev/null and b/smartsoltech/static/qr_codes/request_358.png differ diff --git a/smartsoltech/static/qr_codes/request_359.png b/smartsoltech/static/qr_codes/request_359.png new file mode 100644 index 0000000..e5c15f9 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_359.png differ diff --git a/smartsoltech/static/qr_codes/request_360.png b/smartsoltech/static/qr_codes/request_360.png new file mode 100644 index 0000000..c394655 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_360.png differ diff --git a/smartsoltech/static/qr_codes/request_361.png b/smartsoltech/static/qr_codes/request_361.png new file mode 100644 index 0000000..c59e296 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_361.png differ diff --git a/smartsoltech/static/qr_codes/request_362.png b/smartsoltech/static/qr_codes/request_362.png new file mode 100644 index 0000000..2a66d26 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_362.png differ diff --git a/smartsoltech/static/qr_codes/request_363.png b/smartsoltech/static/qr_codes/request_363.png new file mode 100644 index 0000000..fd69da5 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_363.png differ diff --git a/smartsoltech/static/qr_codes/request_364.png b/smartsoltech/static/qr_codes/request_364.png new file mode 100644 index 0000000..63d642b Binary files /dev/null and b/smartsoltech/static/qr_codes/request_364.png differ diff --git a/smartsoltech/static/qr_codes/request_365.png b/smartsoltech/static/qr_codes/request_365.png new file mode 100644 index 0000000..620f687 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_365.png differ diff --git a/smartsoltech/static/qr_codes/request_366.png b/smartsoltech/static/qr_codes/request_366.png new file mode 100644 index 0000000..83ec5fc Binary files /dev/null and b/smartsoltech/static/qr_codes/request_366.png differ diff --git a/smartsoltech/static/qr_codes/request_367.png b/smartsoltech/static/qr_codes/request_367.png new file mode 100644 index 0000000..fbe1ea5 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_367.png differ diff --git a/smartsoltech/static/qr_codes/request_368.png b/smartsoltech/static/qr_codes/request_368.png new file mode 100644 index 0000000..ee07650 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_368.png differ diff --git a/smartsoltech/static/qr_codes/request_369.png b/smartsoltech/static/qr_codes/request_369.png new file mode 100644 index 0000000..2629e11 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_369.png differ diff --git a/smartsoltech/static/qr_codes/request_370.png b/smartsoltech/static/qr_codes/request_370.png new file mode 100644 index 0000000..3ae6000 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_370.png differ diff --git a/smartsoltech/static/qr_codes/request_371.png b/smartsoltech/static/qr_codes/request_371.png new file mode 100644 index 0000000..1c25c3c Binary files /dev/null and b/smartsoltech/static/qr_codes/request_371.png differ diff --git a/smartsoltech/static/qr_codes/request_372.png b/smartsoltech/static/qr_codes/request_372.png new file mode 100644 index 0000000..305f58f Binary files /dev/null and b/smartsoltech/static/qr_codes/request_372.png differ diff --git a/smartsoltech/static/qr_codes/request_373.png b/smartsoltech/static/qr_codes/request_373.png new file mode 100644 index 0000000..2b19917 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_373.png differ diff --git a/smartsoltech/static/qr_codes/request_374.png b/smartsoltech/static/qr_codes/request_374.png new file mode 100644 index 0000000..ac2ee3f Binary files /dev/null and b/smartsoltech/static/qr_codes/request_374.png differ diff --git a/smartsoltech/static/qr_codes/request_375.png b/smartsoltech/static/qr_codes/request_375.png new file mode 100644 index 0000000..909e4c8 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_375.png differ diff --git a/smartsoltech/static/qr_codes/request_376.png b/smartsoltech/static/qr_codes/request_376.png new file mode 100644 index 0000000..a8a6091 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_376.png differ diff --git a/smartsoltech/static/qr_codes/request_377.png b/smartsoltech/static/qr_codes/request_377.png new file mode 100644 index 0000000..b3bd76a Binary files /dev/null and b/smartsoltech/static/qr_codes/request_377.png differ diff --git a/smartsoltech/static/qr_codes/request_378.png b/smartsoltech/static/qr_codes/request_378.png new file mode 100644 index 0000000..af115b8 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_378.png differ diff --git a/smartsoltech/static/qr_codes/request_379.png b/smartsoltech/static/qr_codes/request_379.png new file mode 100644 index 0000000..5360a78 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_379.png differ diff --git a/smartsoltech/static/qr_codes/request_380.png b/smartsoltech/static/qr_codes/request_380.png new file mode 100644 index 0000000..7462e76 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_380.png differ diff --git a/smartsoltech/static/qr_codes/request_381.png b/smartsoltech/static/qr_codes/request_381.png new file mode 100644 index 0000000..0d5d9f1 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_381.png differ diff --git a/smartsoltech/static/qr_codes/request_382.png b/smartsoltech/static/qr_codes/request_382.png new file mode 100644 index 0000000..594faef Binary files /dev/null and b/smartsoltech/static/qr_codes/request_382.png differ diff --git a/smartsoltech/static/qr_codes/request_383.png b/smartsoltech/static/qr_codes/request_383.png new file mode 100644 index 0000000..de100a0 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_383.png differ diff --git a/smartsoltech/static/qr_codes/request_384.png b/smartsoltech/static/qr_codes/request_384.png new file mode 100644 index 0000000..f5477e9 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_384.png differ diff --git a/smartsoltech/static/qr_codes/request_385.png b/smartsoltech/static/qr_codes/request_385.png new file mode 100644 index 0000000..1b5f303 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_385.png differ diff --git a/smartsoltech/static/qr_codes/request_386.png b/smartsoltech/static/qr_codes/request_386.png new file mode 100644 index 0000000..205d603 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_386.png differ diff --git a/smartsoltech/static/qr_codes/request_387.png b/smartsoltech/static/qr_codes/request_387.png new file mode 100644 index 0000000..99fddf1 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_387.png differ diff --git a/smartsoltech/static/qr_codes/request_388.png b/smartsoltech/static/qr_codes/request_388.png new file mode 100644 index 0000000..fc89186 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_388.png differ diff --git a/smartsoltech/static/qr_codes/request_389.png b/smartsoltech/static/qr_codes/request_389.png new file mode 100644 index 0000000..091213a Binary files /dev/null and b/smartsoltech/static/qr_codes/request_389.png differ diff --git a/smartsoltech/static/qr_codes/request_390.png b/smartsoltech/static/qr_codes/request_390.png new file mode 100644 index 0000000..f4c6926 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_390.png differ diff --git a/smartsoltech/static/qr_codes/request_391.png b/smartsoltech/static/qr_codes/request_391.png new file mode 100644 index 0000000..00f409a Binary files /dev/null and b/smartsoltech/static/qr_codes/request_391.png differ diff --git a/smartsoltech/static/qr_codes/request_392.png b/smartsoltech/static/qr_codes/request_392.png new file mode 100644 index 0000000..18acd10 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_392.png differ diff --git a/smartsoltech/static/qr_codes/request_393.png b/smartsoltech/static/qr_codes/request_393.png new file mode 100644 index 0000000..5815aae Binary files /dev/null and b/smartsoltech/static/qr_codes/request_393.png differ diff --git a/smartsoltech/static/qr_codes/request_394.png b/smartsoltech/static/qr_codes/request_394.png new file mode 100644 index 0000000..e78b9a9 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_394.png differ diff --git a/smartsoltech/static/qr_codes/request_395.png b/smartsoltech/static/qr_codes/request_395.png new file mode 100644 index 0000000..10871cd Binary files /dev/null and b/smartsoltech/static/qr_codes/request_395.png differ diff --git a/smartsoltech/static/qr_codes/request_396.png b/smartsoltech/static/qr_codes/request_396.png new file mode 100644 index 0000000..43b8d00 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_396.png differ diff --git a/smartsoltech/static/qr_codes/request_397.png b/smartsoltech/static/qr_codes/request_397.png new file mode 100644 index 0000000..c948f27 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_397.png differ diff --git a/smartsoltech/static/qr_codes/request_398.png b/smartsoltech/static/qr_codes/request_398.png new file mode 100644 index 0000000..97fd34e Binary files /dev/null and b/smartsoltech/static/qr_codes/request_398.png differ diff --git a/smartsoltech/static/qr_codes/request_399.png b/smartsoltech/static/qr_codes/request_399.png new file mode 100644 index 0000000..1ed790e Binary files /dev/null and b/smartsoltech/static/qr_codes/request_399.png differ diff --git a/smartsoltech/static/qr_codes/request_400.png b/smartsoltech/static/qr_codes/request_400.png new file mode 100644 index 0000000..c417152 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_400.png differ diff --git a/smartsoltech/static/qr_codes/request_401.png b/smartsoltech/static/qr_codes/request_401.png new file mode 100644 index 0000000..3500aa0 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_401.png differ diff --git a/smartsoltech/static/qr_codes/request_402.png b/smartsoltech/static/qr_codes/request_402.png new file mode 100644 index 0000000..e50a096 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_402.png differ diff --git a/smartsoltech/static/qr_codes/request_403.png b/smartsoltech/static/qr_codes/request_403.png new file mode 100644 index 0000000..36ba848 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_403.png differ diff --git a/smartsoltech/static/qr_codes/request_404.png b/smartsoltech/static/qr_codes/request_404.png new file mode 100644 index 0000000..92b63e9 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_404.png differ diff --git a/smartsoltech/static/qr_codes/request_405.png b/smartsoltech/static/qr_codes/request_405.png new file mode 100644 index 0000000..00dfff9 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_405.png differ diff --git a/smartsoltech/web/migrations/0009_alter_servicerequest_options_and_more.py b/smartsoltech/web/migrations/0009_alter_servicerequest_options_and_more.py new file mode 100644 index 0000000..b99f264 --- /dev/null +++ b/smartsoltech/web/migrations/0009_alter_servicerequest_options_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.1 on 2024-11-01 04:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('web', '0008_alter_servicerequest_client'), + ] + + operations = [ + migrations.AlterModelOptions( + name='servicerequest', + options={'ordering': ['-is_verified', '-created_at'], 'verbose_name': 'Заявка на услугу', 'verbose_name_plural': 'Заявки на услуги'}, + ), + migrations.AddField( + model_name='servicerequest', + name='is_verified', + field=models.BooleanField(default=False), + ), + ] diff --git a/smartsoltech/web/models.py b/smartsoltech/web/models.py index 061fccd..4f28d69 100644 --- a/smartsoltech/web/models.py +++ b/smartsoltech/web/models.py @@ -76,11 +76,12 @@ class ServiceRequest(models.Model): created_at = models.DateTimeField(auto_now_add=True) token = models.UUIDField(default=uuid.uuid4, unique=True) # Генерация уникального токена chat_id = models.CharField(max_length=100, blank=True, null=True) # Telegram chat ID - + is_verified = models.BooleanField(default=False) + class Meta: verbose_name = 'Заявка на услугу' verbose_name_plural = 'Заявки на услуги' - ordering = ['-created_at'] + ordering = ['-is_verified', '-created_at'] def __str__(self): return f"Request for {self.service.name} by {self.client.first_name}" @@ -150,5 +151,5 @@ class Review(models.Model): ordering = ['-review_date'] def __str__(self): - return f"Review by {self.client.first_name} {self.client.last_name} for {self.service.name}" + return f"Отзыв от {self.client.first_name} {self.client.last_name} for {self.service.name}" diff --git a/smartsoltech/web/templates/web/create_service_request.html b/smartsoltech/web/templates/web/create_service_request.html deleted file mode 100644 index 655437d..0000000 --- a/smartsoltech/web/templates/web/create_service_request.html +++ /dev/null @@ -1,64 +0,0 @@ - -