From daa5c49bb96cb55f4aab7126b57ba0cffc49eab1 Mon Sep 17 00:00:00 2001 From: trevor Date: Fri, 1 Nov 2024 19:27:14 +0900 Subject: [PATCH] fully functional. UX/UI stage --- smartsoltech/comunication/telegram_bot.py | 323 ++++++--------- .../static/img/customer/JD-26-512_SKOAvnB.jpg | Bin 0 -> 15404 bytes .../static/assets/js/get-csrf-token.js | 18 + smartsoltech/static/assets/js/modal-init.js | 113 ++---- .../static/assets/js/service_request.js | 116 ++++++ .../static/assets/js/verification_status.js | 37 ++ smartsoltech/static/qr_codes/request_347.png | Bin 0 -> 1072 bytes smartsoltech/static/qr_codes/request_348.png | Bin 0 -> 1132 bytes smartsoltech/static/qr_codes/request_349.png | Bin 0 -> 1128 bytes smartsoltech/static/qr_codes/request_350.png | Bin 0 -> 1145 bytes smartsoltech/static/qr_codes/request_351.png | Bin 0 -> 1140 bytes smartsoltech/static/qr_codes/request_352.png | Bin 0 -> 1164 bytes smartsoltech/static/qr_codes/request_353.png | Bin 0 -> 1147 bytes smartsoltech/static/qr_codes/request_354.png | Bin 0 -> 1097 bytes smartsoltech/static/qr_codes/request_355.png | Bin 0 -> 1128 bytes smartsoltech/static/qr_codes/request_356.png | Bin 0 -> 1101 bytes smartsoltech/static/qr_codes/request_357.png | Bin 0 -> 1147 bytes smartsoltech/static/qr_codes/request_358.png | Bin 0 -> 1182 bytes smartsoltech/static/qr_codes/request_359.png | Bin 0 -> 1168 bytes smartsoltech/static/qr_codes/request_360.png | Bin 0 -> 1122 bytes smartsoltech/static/qr_codes/request_361.png | Bin 0 -> 1134 bytes smartsoltech/static/qr_codes/request_362.png | Bin 0 -> 1092 bytes smartsoltech/static/qr_codes/request_363.png | Bin 0 -> 1086 bytes smartsoltech/static/qr_codes/request_364.png | Bin 0 -> 1047 bytes smartsoltech/static/qr_codes/request_365.png | Bin 0 -> 1121 bytes smartsoltech/static/qr_codes/request_366.png | Bin 0 -> 1081 bytes smartsoltech/static/qr_codes/request_367.png | Bin 0 -> 1087 bytes smartsoltech/static/qr_codes/request_368.png | Bin 0 -> 1165 bytes smartsoltech/static/qr_codes/request_369.png | Bin 0 -> 1101 bytes smartsoltech/static/qr_codes/request_370.png | Bin 0 -> 1162 bytes smartsoltech/static/qr_codes/request_371.png | Bin 0 -> 1127 bytes smartsoltech/static/qr_codes/request_372.png | Bin 0 -> 1153 bytes smartsoltech/static/qr_codes/request_373.png | Bin 0 -> 1163 bytes smartsoltech/static/qr_codes/request_374.png | Bin 0 -> 1127 bytes smartsoltech/static/qr_codes/request_375.png | Bin 0 -> 1112 bytes smartsoltech/static/qr_codes/request_376.png | Bin 0 -> 1139 bytes smartsoltech/static/qr_codes/request_377.png | Bin 0 -> 1128 bytes smartsoltech/static/qr_codes/request_378.png | Bin 0 -> 1158 bytes smartsoltech/static/qr_codes/request_379.png | Bin 0 -> 1091 bytes smartsoltech/static/qr_codes/request_380.png | Bin 0 -> 1114 bytes smartsoltech/static/qr_codes/request_381.png | Bin 0 -> 1159 bytes smartsoltech/static/qr_codes/request_382.png | Bin 0 -> 1114 bytes smartsoltech/static/qr_codes/request_383.png | Bin 0 -> 1071 bytes smartsoltech/static/qr_codes/request_384.png | Bin 0 -> 1128 bytes smartsoltech/static/qr_codes/request_385.png | Bin 0 -> 1140 bytes smartsoltech/static/qr_codes/request_386.png | Bin 0 -> 1129 bytes smartsoltech/static/qr_codes/request_387.png | Bin 0 -> 1154 bytes smartsoltech/static/qr_codes/request_388.png | Bin 0 -> 1117 bytes smartsoltech/static/qr_codes/request_389.png | Bin 0 -> 1155 bytes smartsoltech/static/qr_codes/request_390.png | Bin 0 -> 1112 bytes smartsoltech/static/qr_codes/request_391.png | Bin 0 -> 1172 bytes smartsoltech/static/qr_codes/request_392.png | Bin 0 -> 1095 bytes smartsoltech/static/qr_codes/request_393.png | Bin 0 -> 1150 bytes smartsoltech/static/qr_codes/request_394.png | Bin 0 -> 1132 bytes smartsoltech/static/qr_codes/request_395.png | Bin 0 -> 1130 bytes smartsoltech/static/qr_codes/request_396.png | Bin 0 -> 1144 bytes smartsoltech/static/qr_codes/request_397.png | Bin 0 -> 1092 bytes smartsoltech/static/qr_codes/request_398.png | Bin 0 -> 1093 bytes smartsoltech/static/qr_codes/request_399.png | Bin 0 -> 1121 bytes smartsoltech/static/qr_codes/request_400.png | Bin 0 -> 1161 bytes smartsoltech/static/qr_codes/request_401.png | Bin 0 -> 1154 bytes smartsoltech/static/qr_codes/request_402.png | Bin 0 -> 1135 bytes smartsoltech/static/qr_codes/request_403.png | Bin 0 -> 1135 bytes smartsoltech/static/qr_codes/request_404.png | Bin 0 -> 1114 bytes smartsoltech/static/qr_codes/request_405.png | Bin 0 -> 1169 bytes ...9_alter_servicerequest_options_and_more.py | 22 + smartsoltech/web/models.py | 7 +- .../templates/web/create_service_request.html | 64 --- .../templates/web/modal_order_form_old.html | 214 ---------- .../web/templates/web/service_detail.html | 175 +------- smartsoltech/web/urls.py | 10 +- smartsoltech/web/views.py | 377 ++++++------------ 72 files changed, 480 insertions(+), 996 deletions(-) create mode 100644 smartsoltech/media/static/img/customer/JD-26-512_SKOAvnB.jpg create mode 100644 smartsoltech/static/assets/js/get-csrf-token.js create mode 100644 smartsoltech/static/assets/js/service_request.js create mode 100644 smartsoltech/static/assets/js/verification_status.js create mode 100644 smartsoltech/static/qr_codes/request_347.png create mode 100644 smartsoltech/static/qr_codes/request_348.png create mode 100644 smartsoltech/static/qr_codes/request_349.png create mode 100644 smartsoltech/static/qr_codes/request_350.png create mode 100644 smartsoltech/static/qr_codes/request_351.png create mode 100644 smartsoltech/static/qr_codes/request_352.png create mode 100644 smartsoltech/static/qr_codes/request_353.png create mode 100644 smartsoltech/static/qr_codes/request_354.png create mode 100644 smartsoltech/static/qr_codes/request_355.png create mode 100644 smartsoltech/static/qr_codes/request_356.png create mode 100644 smartsoltech/static/qr_codes/request_357.png create mode 100644 smartsoltech/static/qr_codes/request_358.png create mode 100644 smartsoltech/static/qr_codes/request_359.png create mode 100644 smartsoltech/static/qr_codes/request_360.png create mode 100644 smartsoltech/static/qr_codes/request_361.png create mode 100644 smartsoltech/static/qr_codes/request_362.png create mode 100644 smartsoltech/static/qr_codes/request_363.png create mode 100644 smartsoltech/static/qr_codes/request_364.png create mode 100644 smartsoltech/static/qr_codes/request_365.png create mode 100644 smartsoltech/static/qr_codes/request_366.png create mode 100644 smartsoltech/static/qr_codes/request_367.png create mode 100644 smartsoltech/static/qr_codes/request_368.png create mode 100644 smartsoltech/static/qr_codes/request_369.png create mode 100644 smartsoltech/static/qr_codes/request_370.png create mode 100644 smartsoltech/static/qr_codes/request_371.png create mode 100644 smartsoltech/static/qr_codes/request_372.png create mode 100644 smartsoltech/static/qr_codes/request_373.png create mode 100644 smartsoltech/static/qr_codes/request_374.png create mode 100644 smartsoltech/static/qr_codes/request_375.png create mode 100644 smartsoltech/static/qr_codes/request_376.png create mode 100644 smartsoltech/static/qr_codes/request_377.png create mode 100644 smartsoltech/static/qr_codes/request_378.png create mode 100644 smartsoltech/static/qr_codes/request_379.png create mode 100644 smartsoltech/static/qr_codes/request_380.png create mode 100644 smartsoltech/static/qr_codes/request_381.png create mode 100644 smartsoltech/static/qr_codes/request_382.png create mode 100644 smartsoltech/static/qr_codes/request_383.png create mode 100644 smartsoltech/static/qr_codes/request_384.png create mode 100644 smartsoltech/static/qr_codes/request_385.png create mode 100644 smartsoltech/static/qr_codes/request_386.png create mode 100644 smartsoltech/static/qr_codes/request_387.png create mode 100644 smartsoltech/static/qr_codes/request_388.png create mode 100644 smartsoltech/static/qr_codes/request_389.png create mode 100644 smartsoltech/static/qr_codes/request_390.png create mode 100644 smartsoltech/static/qr_codes/request_391.png create mode 100644 smartsoltech/static/qr_codes/request_392.png create mode 100644 smartsoltech/static/qr_codes/request_393.png create mode 100644 smartsoltech/static/qr_codes/request_394.png create mode 100644 smartsoltech/static/qr_codes/request_395.png create mode 100644 smartsoltech/static/qr_codes/request_396.png create mode 100644 smartsoltech/static/qr_codes/request_397.png create mode 100644 smartsoltech/static/qr_codes/request_398.png create mode 100644 smartsoltech/static/qr_codes/request_399.png create mode 100644 smartsoltech/static/qr_codes/request_400.png create mode 100644 smartsoltech/static/qr_codes/request_401.png create mode 100644 smartsoltech/static/qr_codes/request_402.png create mode 100644 smartsoltech/static/qr_codes/request_403.png create mode 100644 smartsoltech/static/qr_codes/request_404.png create mode 100644 smartsoltech/static/qr_codes/request_405.png create mode 100644 smartsoltech/web/migrations/0009_alter_servicerequest_options_and_more.py delete mode 100644 smartsoltech/web/templates/web/create_service_request.html delete mode 100644 smartsoltech/web/templates/web/modal_order_form_old.html 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 0000000000000000000000000000000000000000..887a59252d12b918a206116864b42f3883f03a9e GIT binary patch literal 15404 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

b5jQPpZPSCvQgU3UN#i(?8> zL^N3(=r$XfwPC3UgKF3x;R zH4hHmjna&AcqL>?WXmIki-bkX{CS8K%NXPfI~frYmoOWG>~lUY&xr9%xvnQ8d!YANOKkCM?1$Mdr<*-$x#Gg+U9cV z_Wbwn0Nfw!+BSw;DYmzMSmMW+XS%2lO4-zb^x_5N6|_h`7Vu&rK-05TXZMg z-`a27$yUFjPjX(6#wwDgjuW~r(!z#>DyE#pKj4f!+3E4%FzBjlzd=fyaLx(8vm%Y8 zl2{x|i&hPdC|@Z;WkqdB$WT%mOpRHFilm9Drv!y7V<1l#OtD}*-yAqHNvd(+NYA&} zw}nJN?OapjBf9Ll>&{LHm#JPmfM@b8wx5E`Qlq>{y^%ZJ=lPGWQH+AF_sPhN;xo<} z+VnN-(x-Pfz6xKP;%WaCP92BUuww}@U?0Se#|m{4ze6dNKYJJZZ%%Lpc3?1X@Z;-s z5uH=e98H^35_GcF?~qIVawea248+|s|36nFa&Lwk_k)FALB}M&pEmn6?0Vn_-Mf=q z;)JhE1)=UZ($*P*A$);JKC54^h{2l+FP|1Ad0%Cej3msOI^f&mp>=%shurX`^&kTJ zBqKf*-VXTsYsM1ZsQaJJm(fT*cC^;s)m`C`e$~d+E3c{+60dLk8zbPc!C}RsbI!I8 z0@dzMP3BWC#ZK}>e(B_WN+31+4~(J@A*xRM`dd7^u0n7!Lv#q%XsDK5VxaQ&tzye7 z&G9zSW3OH!baQA87a!fMWf)G{wBQfTjhpKgE$ZW#4%nI>ZDdj`!(BR;irWpNUYU|ZY*>#M8((CW zJp#tVl~;Y8M`|519dAZw$MbA`-TvB&G9DT?NpEv=b`3Hv>ZdItM}4%AH~TP{mO#>y z42Y3^^%6Qx)ypeo20xc?$TFP%>*!2AlGh6Mx;UEp(zbz?O9!%JW9)R*-!!tp&Uy8+ zZF!2h^wGZTK?%~kaX9AUXDw!D6RtNUr+reJ|FMR${43L7?3rufck8vvM=k6<;}pYY zt!YxNoqFp@tOUO*W|B5QPM$7qqx#+_ZBYxlhn~z*sBAiU63O_vsAZ6e!7bV3j>G8w zTGy*-GtEizX5=danI*}&6U+BgSW2&T#HVN9AKyg^E{aE=?j|NfB26<$c32W|lSf3f z)GuWCY5;z}7SD|o$vbtPHTm03%BN!`t&m%yf4~(DsFV}y9K8reWN%(czW}p%Y?{bC z8Z3QQRfhD;xbGC zEB~60vsYdY-OgJaoXB?t$##)DM32S2>MN!GA=;LNASmZyQGez-E6O9uBeRA$cc7Z} z`+UWK>_1KXn#~cbY8038{niER37tp()Sl^2^y2#)tVFlAg+2Vq@zQY8cfLH$NIw)K^P(Khim;wm+G#4fT}(W*TOwn70sV1?QiL zclKIhshv#m#B=>iCyD)rnhD(avde#DRux0Nm*sPExH-uKd%(QG(QQ|g#By0s^hhvT z?VgiF`-G8A+uVsAFZVBaqP<}Xx?-asrRicLS;0^URQUIyj%ljnxQD@ppXxMsi1;z< z_7H#Xiz~gh*~oMC8-7)!g@>leSLDv;p8pcoF_s-i-(fLPz=`706nWV>a$Kbh11 z+->|s@R9=MwQJuxOXM0`?kEG { - 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 0000000000000000000000000000000000000000..20274e5e6d6326304d24417a74af9ecdbbe1974f GIT binary patch literal 1072 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 LNkvXXu0mjfnh-K? literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_351.png b/smartsoltech/static/qr_codes/request_351.png new file mode 100644 index 0000000000000000000000000000000000000000..7fc93fb19cab0d9d5ab0640440764a1a13f622f3 GIT binary patch literal 1140 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 eH{9_51^zD!80!a$;3atg00001cdvEP) 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 N002ovPDHLkV1n~MK|%lk literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_358.png b/smartsoltech/static/qr_codes/request_358.png new file mode 100644 index 0000000000000000000000000000000000000000..78edf7f219f7824591c3ac6232b17c433aca51fc GIT binary patch literal 1182 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 ixZ{pH?zrRs3;aKOuF{|B=bgL&0000 zO>W~z422&@1!O4!IY5q5zCj-;$dUR6(ouYX0aQx^CA?YGZ=7CPY9t;#E{y2sL)id9 z79T0ah#j{4vxf$R3l}b2xNzaZg&&JsHV3<4GrIstA7*Cl79f;cFUPGe{G_-iNv;5A z06;L~hq-jYF2R8$X%`G6Nq)w6t}gtfc(5+Q@nZtuR{+aY4wq@GQO_N`y6|)1?(Ucf z6X3Zy^S?JE0GMAVBf|Z?`&So!PW+1}Ex!l@04~!I^SNn=z__Lh2d*ysoOtoNkpKc< z{^}x^Un?xT*%0C9asdJ8b>*l2?ZUqqU(C#G$|vpp>HvRrd2?5jt6i{Jt80JAmlytQ zcygx}zKF0Hfc}F(1TaSAn0VOg!q15(MFf5wigGfNK=~jU0neDC9?1xD9hkJ1`Kf=q z@bAWRAR`dWfZ)J6IM^jP0O5sL-XiSscUBjEEbl@zJ2z>xE=yiWLDJT)G|3v)9zH~{0#IH$krHg5&U_2AWo zpA0Y61Y7yQKAP2BixlPniC~TIy|{*qJh{@Q18diHjwv zBo_^(Xl=wSCE1nk1;aWasAh#t@rMgsCNI4O{&&p(Q(dODYzYaOCHoZ9cn!HZ< z0XWH9((B;YJX*q!R5T1sJG^BAI0vg^0f((F{A_sXh_ya!3S_k-!Pv{fe$~EC_;DRE zpi8N(XiaW5)-GAsDwEd+^M7p9M=$z}!lVY9l$F0w>t*hU)#Xf6zW0P6rb;2LDR!wjoOI?u* ziR@h6q#Z`-b;6HRiIJa&sLBcJ7;!5pN|~VyD}0yr9kCk7x{y|;+RGe(_I1LKjCH7m zL~^t4ux;~3QYx|Vo%kP~hkd2_bu#$hlL6tC@K*-{8;D?lZ?`}7Zx{YucvVjBvT5uj zm3(0=G0|6nPq9w;L&ncmW|<=T-5iQ&k`I+(h407PyE^mEExZt(H{*wym6x65$Fs}B zJBO_<{G_;VqFuRSHUakD)RYxS33qwBY0^pf9_#XI-M*3auNj|aPJnWs_I1J^wy*Es z3A%+r7cN}5aN)v*|1a?W0EiO?Xg}A4W&i*H07*qoM6N<$f?m)ZPyhe` literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_361.png b/smartsoltech/static/qr_codes/request_361.png new file mode 100644 index 0000000000000000000000000000000000000000..c59e296c52e0601626eccf65ee13957bca313470 GIT binary patch literal 1134 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 R-k$&f002ovPDHLkV1iIo{&@fZ literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_365.png b/smartsoltech/static/qr_codes/request_365.png new file mode 100644 index 0000000000000000000000000000000000000000..620f6877d7cdc422595f4eab5f156e48b9adc0ba GIT binary patch literal 1121 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 TeQ5ij00000NkvXXu0mjfq=FP_ literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_370.png b/smartsoltech/static/qr_codes/request_370.png new file mode 100644 index 0000000000000000000000000000000000000000..3ae6000d20b965fe6e83e3463a94639cef6c6875 GIT binary patch literal 1162 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 literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_372.png b/smartsoltech/static/qr_codes/request_372.png new file mode 100644 index 0000000000000000000000000000000000000000..305f58ff06b8762cf72ec3920437ff9096c933b1 GIT binary patch literal 1153 zcmV-{1b+L8P) zTZ-g542FN580yi1SwJnt*}*Jnm?g~)lBLuF8l1-h2b~95ak~30$)ToBenE%aK3oAI zSr@xSaX_Yjj?e&c;>3v)Cr+F=@pEyh5+DNrOcH>pU!p zRU}na&7H*-I>vgbss%ctQvlt1&x!G^zn%E2@wu8W9iyuJdIX5vpCSV~l_3@&Wk3c1 zA`(s>o%prz@a0+%mw@SBpa2w8pP`sT(W&oFAD#F$@vmB^m~Sd+Tmle3f?^H@h))5q z$l0S4zb5Wl7Ztz^0MX2xi6CYOVpd@8p_qYfUiq!Ro%oCKNkl|?z(duWB0X-3^awzD z1c=S>uviFt>gdEThMTSXRu+o|I`xoh+-AV%dY@l?>u)FiD%>+C8PL%#Jynu&r$Ag& zDi+9gs$(o*=7jiusq?z&t`NkJAn8vJ0E_5!F92qNS|Bk8SX_}FHj6oNzvq<;yGIX8{0v-2^P#GkdH~bC zS~vimirk-KVa9K{nRfm~Kc4tI;j67Hs0I%}Gkr)IZrpOGI-*7s^svMah&CDFrG1NB zwN_uZv$+hoCQ|E&?-f_M0&}0MxN%#jd48`NL24cG-O@r;U}NiwUAomJ_W&Wi&y2zts7f zrHad^kQTMcvua&CbN!>%5#J|m(q@O00iU@QcpzKL5=Kz#h#$kf=Vbl?q!HdhH{VRd z1n~p)%>DpLxo4*n@gw54ZkvqT+CPt1eVW&LQ)ugm?-h?GJV2<9wA*BfHwijzUYA-& ze7AhpwHh>3y@DIJ(KC0hdel1Ndu0>DHsfX%&Rd&2hHaY2%n9-1xQ@0S;#S*DYT*5`cVcqMpB1Zg>G#ggMRqtDFxUJU7tW6L<0Z;BTksczz+CgXQ zb}Xf`h}Fh`x~JG*^5coW8@|b$0O*PxQtn05BNPRe^_8wjO{tWir;JYg(s=U89e~C5 zO2p*5CbqmvYrH#kbmAAoH~XA;8{K-Qb#hmCh>gB(F)3H;5I++a=>h%S``I{)$gjLe z-BV0`jrM;sI`M1ZU-#++VumDL1ZiBXA_m((%r;D1f=1T literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_373.png b/smartsoltech/static/qr_codes/request_373.png new file mode 100644 index 0000000000000000000000000000000000000000..2b199173d82832b2da9fcaaa032b3671b6aa61e2 GIT binary patch literal 1163 zcmV;61a$j}P) zO>VSE42B;MC1qJiIY1u;ZZJn`&5^zvz)^C5NU&@P^v#2jBO*Jk@Yl^Bt7E?wL5-Me9rF6`gHjwXKP7uJ%!pYhlzcwyS zBnz`1pqm=meOgTe&DSc+@AdGGzbZc779ehM6?SL;wRXoZfspgpAU=$= z88HXwJ_2_C2v{E zVLa7=pH-z#Eze7 zb){ZX>@O!53)|iV&?woTTb<+ImtDPXfL*G(8CSMMEoh*oxo&lipMcw4Qm)OltJ!@5 z#uk7^rBs*Kb=IG(-SG?J@lm>kQ_%$Umj&pi)zSe-YrSNSr)qcnT6o@v9jy_t1S2+r z_!+F5S~Rww08Ms+M3rW!GqgK?P5euz6S1VUsf{z%HC$To<;G9XCLBK?TWw_9^WVlO za!EzSxut4~@BTY}0%$d0!K>rdA1_|@>@>z*qj)tlueC*_`} ztr^NICypPGf9_4_xfuL!O?CtLy3X+(RV*{{u^ z*cHHdE0wze$ioxmKI_lZ?)cU4T~}u^sTxR&ud9c;!gF8e_%Xbs1Y`_2I~e8bD6d7ruW6VUm^e2ZB6Vi{qBzc6#i5>nf4!>D2I|<p8heCw z{JWxO+07^pP`WySl2=H(ty;G_$G;hbLm~uZzmF6t$#Rq_hfngmwHo z62AO0hlSCAZdwD-EY=Nc00M%w%xw=RXm{Lk0K3<(HjNgL^hg0WIl(-w?H%lnAClev zRvm!N+x@XNo@_zb_hB7Bj@Nn}K>6Oaa?AQQ6#F!aT`keA&hc-F`G2o-+;PVpcieHu d9sgh8e*-tm=~dpw;Ise$002ovPDHLkV1n^mO8)== literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_374.png b/smartsoltech/static/qr_codes/request_374.png new file mode 100644 index 0000000000000000000000000000000000000000..ac2ee3fe06b004ddad5589177eda7227d0c6b7ed GIT binary patch literal 1127 zcmV-t1ep7YP) z&5h$a41hmA8_3ZCrhq9$?qEwAY)RXJT}ldAz&-|$!FLd8D;ex1_98DYpA=$v>9q&`Y%`1X|Oj1RMK=t$Nu=)0}mX4@l%yiL`2SwCG*C!Io!WKd*E+@yRGXKm_gE|%{u;= z5V{G0CX)t`G<~4VQ0v}HuRZW5<7V9Khw^o4Azj+Cxr5o1Q+k#X!X7$%;BST(b=u5V z+1J%?izsBE%a~0(Z1%w46Zg!?)TrtNB}?KOrmC7DX)abzRWqtn6Pc61_ejyYO2Z~7 zN;uHyHY}Q$iq=7BUEn*!62Y2noYpMyYTTg9=ujT2^>;75_Q0QoSG5Un=jv8(vvvM3 z*PBgQL+b+Hg)ahgiw=MVt=&~@*m+ru`BW-r(jPi|;BSTB+dA9k(G)fFiY%^<{uZ__ z@I!FbOAF(95$LWWJ&SyEu2}dg{lT*b{zkahCgzVUbQwvPlL8CMT;8N)>C)w-C6hP) z`0dzBuRZW*;dQ6eP+FTZ?r{CB{MKzK(i zD#dud+2M_GZX)n~a#M`RYva>q(%hS>=Bf`WGADuWkZoUQ`MPN>f&H<`ZX)(|f$xzj znkY7G>!rKtIZ^f2I*Thp>jHmRwk)xmxuy&0{&Ki`*!8e$s-g+kFiW3oH%>&pF7REVt8BTsI$m8PjI@3- zL<}4FKC#Tn+B~-&@!!r!cnq;s#A06;_%3lvm#fU(c2KbnWUG2b)FuMoB{#apybG|Ot=R*A5B&bF&Z1Le z-vHh3R?@Ez6*@)IMXdW|{LFsi-Ak`M@Mqzsbz?bS-5>y(bP?dBjGtElmKHii?6fxF tVFTYG692s}@W2BPJn+B+5Bz_D{|gt=6d9974gLTC002ovPDHLkV1hcoFmwO_ literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_375.png b/smartsoltech/static/qr_codes/request_375.png new file mode 100644 index 0000000000000000000000000000000000000000..909e4c8110d424b9642c5ffb135df5eac9121329 GIT binary patch literal 1112 zcmV-e1gHCnP) zO^V}45Jq2&47HS?4p2u?-K>}+^$nz>_y7&kvOwmWMP@3~?ww_Dd+LjYktIE3K@gGg zmkx12=6{aRVBENI_33^Ero$6KSCB~&ar|G5N-T1TcqIC-}F5P|v($cm1H?g0iv(_0uAg7z}ng`H4 zbX$zSE+K#zm!TZ}dg#-Q|4jT=>$3E}L-WvW>D&AvfNqQ1`(FCpjXw)7TGtC$lU)Po z6!Z%L-NraUjLSP>g*LDJ((i8k$@m-*5d#37;_G~Z@q9`vycEp>#3z>&!anrr#(x-| z)Tx>;vF6N4Il6>k1Nx0@6Cd_;<3AJMW7tm80-E|p!z5{gQCo>?wdFw8F|6_XC21W% zPRl{cp=hFOQ!4aX|D+|~Y^^hXpOl>MM#{)dea;tG;|Befj9|Jtfwj)~5oxqeyCa?8 zHffyWie3L?tuubNs7fk0HBVc_?!EIXb&9xco zFZuDtUkh(Lo$9(Sw>E8U(u7{c2-cP0OTWAEXW>^KRx15f6Fs&fMLc+s&c1&iMV(W{GPcyVu6{Vr097-A#Bb&JtQmoDr8$Tpv zT?eVinhRg8>n#Q~w*SY7!_=7Sh`xGoWL01yQ&7fjg z;pJv1Yn}1CrMT1*zUJyfZ78mZyi%6+Jgo6!_#VSv=SEa*-Tu+!>o$8>;|HWn>#QeW zeN!4moCBc$4(5;VNJnW}aedzy7ZeY9y78ZhmvtRbD_u>wziELgA%%O1jX%i4)~}6A zZC!6UQW@j1))~K7uIFJdr{Ya7A=UxL2{E2e2vCgYfU#=nOTWAEXW?x{tnTDA*6o~X zrN3`mpzL9d9}rzjIyV8e1X0dauj@Lj@#A>itFxv`QVu2U(3#eC-;qnOuEQEXBw2sP z31EFE?`Z-A{h}C`0kOWN#a+?A-=3Q=enfH|c7f8yUK=`9w(0Eaj2KXdC+uO3-zB$N zHe6u)c3W50T=JmwtES&%(q1UT566apT5~ e8#n&H!2bj8Pf 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 literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_381.png b/smartsoltech/static/qr_codes/request_381.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5d9f182e5c2c0601a5f5f6dae5d35eba1f0334 GIT binary patch literal 1159 zcmV;21bF+2P) zPmZfN5Qo1Ska`JHA0S6@ZZJoBdPjOUfTQFFW*N!RZx*(}X=ygVs5_IY1x*N_3{t7e z^)GGWfXsg#p}}#-9e3Pu#~pXv@pEx2(qm>lu$XOMFq>Jqw$xj%=dJGeo8m!|6hRXJ zLxS1*`~@L)vMZf{PLiZ&{NU=2zZp)}p%8%(JHb%YOp2W}4TGaa??)Xo^ zH7z~NY{5IfngTMy7FU;FP?cl=%PA)$#*`aRZ5^Vt1MTJNVlyyGu{_vP;(U;zua zKEV*Ne4tB&seB<8Xch3K-`(+V#%D7#8_UJ)Qp2q$Z}?b>a@v(g4q;DS-SIcWvpQ|& zODq69Oe_y8XC!i5n{DE0t2_Rl_!`4@HFGjF8YW2zf>O46l4>C9F|6YUas9sB&8|Zt zd(&|Hkfvoz8h?oSlCW#09`0csKOlYkVfhr$rL18gj;8qv%$K`q{u{(HVh!=q@9y|_ z;cb?fK_xAm{c3ik#ktm7ivP_O3iq&%?~q>08dDyI6(;!usT8kE|b#$$B{3vdAxf{@l z*?R1kB*M+CSVF+AkgK$(ukQF8;cdQdg4LRpCX?!V)4JhXU9a0Z$B*GPe2`$c7ef|q zJbAz^k&P>frj&l=TR+wFeF!#nm1)L zjn;+L%r$#BsENGwF!?;JsXgYtR~@G`ah} z&hbN1=V2EsL$UJ+%vZ25Wxtv%#1TR2#bOY)nb?Wad&V zO^V}45Jq2&1YXK82dJZ@Z_r0-=16@5=_o!xfwXLpiCJVuDs6gYY3Q!e7mLC!>yc#$ z;_nNo%-LbnUwdc}E?l^9;lhOr7k(^m#d_=pm|Y(hAN0V|!*qQZEOF`WxYLE76i@E% zK7;>bJwWG7)QY z=gxu7v!9M%`nwDNU3mZU-luD~TAFcKzyY^3U(Eq5{W$b=;pfC(y)N67tGaG2Z?D}7 zbZ!TqF8rK$c-`Q@0y(Zt-#&X7W(>NOG=imjzk0;KgH9KIYJ4&?vnv3d+xPp$N%uaA zyQMg%-FV~{_R!OXpA66Lw1qEc0pMZI^04xXXk>FtJnVGg=frCd+m*@5IJj32b9Z0M z_$1BX?$OAqhZTMVZnr#^Gb7zE?&H$eDe=XbK344ZpPerJM0k#MIn32q=OcA;2b7^* z{6OPvu*#;mGb7KG}JEDz6j%u5H}} z$!j8o68c8E+O@V>S6(N4hZV1jKvq&}==-^)-6A1X{a0Nl{0Q9aV};53ym%5p@L{=| z$ORw7&eOrC3qKLw#=4QN4S0FK$vw9ZWri2AP8nAC4vWc2cvG|0v^iXqbcN8ASoi_B z*~d>~GP4M2Wxv>cei+Gr8q-Iaq1f%<(}kZ64;^;7xG{Y8mhSy(aB)jNt{B57aY>JZ zll||I(}kZCuXSB$4#cP=WC{0>C8Eu(1)nmk@b|2gZ$Q*=txA?>c)m3kv+6qGhvCBt zETyh9yT%};+#Xg`S{U5(mcXH>3qKcLV_oT7i~1GOY#SP99W1N=gA_60yKGa$O6Htv zUH8i+yUts^>`Q-l;lB%ypjDTb8d)rERD9hC$SRquhc$CURAR-D^`93VY^|5X3P7szg}hGqUc44< zJ}%oMVQHSOV>cit-09<|?wb(4$4aX(Q$^Oe&${-jF)E2oleD!SU;4WX|AX*{6@7nx zE}N*^Oa7=yc)d#9!~i zE}3(a#Tqdd>9E2N!Aq=*2N9DaT=Itj7mv>2(Zk>v%ipUpfTi(((}kZCH~sfI;lhOr g7cN}5@c#w=FSh zO^%~T5Jq1NNVQC)IzSx-->fx9nj64Te1MiYXMec>{f$0ZoNG2>B8R)$KBoO z-Q9g^9BAB!+e_P zFfU(NBG$`e0ZaKwRww*^9pbu@IfRGXYAEqhty5Mf{Dg|Hiz;1K9|KJ#uG{9D2w$hT zPWb(b-o*S#G-Eq_>@Wu~lEc_FSU;?7Zi_wc>B8R=j}mu1{7c{BHSPF-EspST(p>Io{A!2)Cgmigvoj}=y@DtisiM{ss!|NS;6Jd#(IT3zJ)y@5P z<|LGDZ7Z(y^}$GPESmF`BR#)fNk5!Va=#uTf%IbvQtD8i%`nuTrTGH37&Fd+y6Mny< z51Z92&iv`t|I;o;ny|5(c2|x0^Ki1$OTWADC*wPpmcGNv=9b)jEq$;!@nrn^R^>$a z8P#kejH@{=v*p0pQZ&iZ3M>4SZmq8DJ!C%z;Podj9Fm!Y?%l*r^<=&bNDvt1jO+0ez!zD7q(8YE3OlM p4mbVxI^n{F3l}b2xbQy${}&q@Y~}{8O!WW&002ovPDHLkV1iuMERz5L literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_384.png b/smartsoltech/static/qr_codes/request_384.png new file mode 100644 index 0000000000000000000000000000000000000000..f5477e9f35603b5922026b7e6c1adc479f9db2af GIT binary patch literal 1128 zcmV-u1eg1XP) zO={#w5QSfi1htf)58$JuZf1O>xq)<)IzU5eX~^QuBJ!`@Jq(mI*hViFMuqf|RS?8~ z$VMEH?XM#=AY8a`;lhOr7cTr<+_H@Q)dB#UnE|^Qw)x>#F3WkR3%?o;k|Y92G7cn} z08Au+!EgA-5C{L$5$m`9?ZQ7B-?RC$Wgo$HHzOl}Z3ejFVSIZ@;0nOZ#*jw5xk!AFam&udw$Hq->04~TsQz=vm3F^0JeF^#k_X)f1fV=5_qw769Mdig*aPQ zu_?lUAt9`8@Di~Dy#jvg-!A-<@y*Q4W&prId%cga*ZT;B2mpKWunQiZ!k&7%@QdND zPR)D~I{**q_J`#wBmk2qw`ZO%{F->FoWy}-1h`IQ)v#Ph2~2MFNG6bRP~}AUVVrL> zV9S)?6=Cc*a^1&LCE0Jp_L5MX@IxL}_z`hihl%8hYQr$ljoS(Um=d^734Q|rWb1?< zkmg~tOO1dRh`kw6oNLZ2s{T=0C;Vy2>Qjwdj@B29C_w~9JEomjWx`i9E{|!vNbCrh`{=8)UX@%b@)f)-O(Ok)9 zfgINM$Fg<84@g#@+S>0|v45Wk@JVCEb;8fXC(@SbJ@4&=`^{TrwqT$wQ}PX-R#N^_ zUtak4!+m%?Ppg+^?0b2;$@Fgh7_m>EoOrtMYvI+y0)4%twIFTfMF=TPr8AE>x&DA^ez>j#wMA8-A&c zl+n6w$T*a0i?mMoQ_}7J6G*VYhY=X){J32p&+Z<^j{zw+$qdf1GtDO6x*F!S+Hh#8$G86N!aocDP3uJ4m~D6JFz ulo6wfG0000 zU5e{Q5Jpc$g8L|g7cfg{?QF=-q@{QP7ocq zGXSeO^J?Xa1?U!_d$h7I{p`ZO3l9sM%_sQKRT}2*zCiLNpL*`TP%N=5tnjBLyJ-Wv zN&(Qg4_o+(Aa@`1|4A z-K?L@pu1bqKWicRJ$Kpx3Pgm9s{g{z(z>l> zGgn$8XsuFp?prg8>afC(N!4>QbbD9vLt8*8TI?+VOJFbk?83hbul%~od{)f>T~WAb zva2)4(mLVKNmUUW_QGpaDT;G9)eW81nJBFj{*=U77YetZW{+*0QMB0BN$Z3^Eqg_* z#H(A-kYZ$Pzgta^$*&XsykxBdVjis9V~D*NyM+{*OcZ_`f6UjFq)8lj^%QJrJaNUa z!cRTxfX#+RyGd3vAciO8*9kwb4tv32ZHr00wUp-d`RbOY>tboZE!_;#uB9*i?83hb zf9PNjr|oN%q7*3nq0?Aro$zD$UU;ycGV!19mk#1+txN9t#dg-8x4ZCn!?T5rLBnQ& z`GP^SSen+>$GGLN0`ql&xs3+9mwtBP--VY>;WPluSA6_fTF+OPDZ6x(p~MT3IsUDA zSm8$`vcyFAO0)Hxc-0mVGujZz75R0-Ps6vt{xq#-J&oIEzAFA-eicCf|LiXO9dY}d z8YkV_JgDRDcgwE=7--5Y&-kIa3E_vNs&Dx=3OfLGF?Kh?TdRO9tnlaMp*B%w|4T)z znz-Id6;(5Uv`+Yw@-OdJ|Bs^oUMF0*aN)v*3m5)V@V@{I93Tses@+cj0000 zO{(KM5QR@Y3o=xo7m%eWJGoEkZ?KNLezs$a#3 z9Wwp5hX#ZT7cN}5aN)v*AB$U);8$nBuJuL$CJO+t7?AzZ>v5|Ke^We>BxitQEZ~>} z_-O%1EI^t8v-3az14)vP_|DaZzZs6ILum$(=B8Ij^}B&UEa134{O}0JmwtEQ-v#H0 z#nvlw9%vskz!3xO`e#=c{vLSv-ItsU;B*~I{XCuh>fqIdzbEcm7YQH(mgX~n_%i@; zh5UeDcT@z(D)BooFAoPy-1dH|4Y|mKwqyy1MW;!>c;2 z=8MPxfW?TsSi3?25DS`3JZyF0?}_&qcIcTCvTGPgmQDJEWNCq{Vp!q3@pv~Nl0Y^C z@`)UCXjx+96ER&1?D}U`7ye$j+q!PU);w^U;isBr}g zkZu9?aSLdfyI6jU?_6E@+u+sKaf~EK46G_uO<%Qt@Os(m|8L6TT0B$P%-sg=e_ci%sk5!y~$fC#@6yw5<8M^<%So zfR`oMn(S&wizvTN_%5khhc#(3yXy7UVy~BV3n#4;zE8GZnp?QlhpR4KD@(X0w%V+; zPWZFpc5UFAs{7*H)sN_wP=1~8BXG0J-P$NvEOj!6pO=E#S~s0nm(JDkz}1Dn8@{o1 zZ4Z42X+4@~!R^`yrOb)&9kRM~o1g*cMgG{cDfGBv1mxEV-y==y+=kVPY}YU!S@ed^ z+9lvNQCcVbDQN={=@!a59#M_mbh#T4OK4r~`Rq^*#nO1d>cZa{w=2-wO_nydlWwP) z$g?X3+BNoG;&n3nJN$UzFNgOmu}gBl&MRWwrTZFYXonU4thisd&B%GndM{d_XY+b5 zyZk!gJ8`=LSp7OAKWCzLI@NZkdUqg@Pk#2qclhzbUk>+q*nA>@B><7|?ztrZ7)lE% zPy&$+Nb8RL((f+(Z{eHj|62I>ZPvHmv?hpw%@~DtSm95}X7--|VTeBik%wZy5|C~u zHq)0wJMjehhcYL^_sByGI}n@ku-;YI!UxYBtG`b8KK$2donDMx`_}1oSZ`=or<3p_ z@Z66Y#$tBOWv vbJ>&Xu)=qV>EG*w3l}b2xNzaZ{|WqmR)HAs__4b*00000NkvXXu0mjfK{`El literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_387.png b/smartsoltech/static/qr_codes/request_387.png new file mode 100644 index 0000000000000000000000000000000000000000..99fddf1421618dedecda8f46a6967ab1ad46895b GIT binary patch literal 1154 zcmV-|1bzF7P) zQHtY842D0g4gKiA9H5U_EB(OBuS6>&ea1yDL&Qh%Wh*MeZS0Rw-L-PvwgnA%KmrY z>VcmNZ$G^k6Ocw^Fq;5bx*LKf+h_cx?>+D@gAW(q;c8rk&8y$Ndf=zPDOp<0>l%^9 zM(Vqa`c5^QOH%!VM$hY#B=s+S?}7hed@wV!Oa0Jp_cz(?-a;CoRI>nfWiBP`p{oae zGQ7Cc8b3>3S5mrZw)%<;bQ$O#L+wl7d*FWx_Xu0UC#df>9wte-$|q?ANtqgnBfX*Laif0&pIpvjgrx1=8}mhLT9wz=+St3y@~{G52*>omfe+?Bj8l^hPL zaY?a$uHgZAaIKLzye{yac)Hi}ff_?4(tVNTx(sQY zjVc;1b;XzX@`1lBKAYKlhT%O!y0;Y9D^57IORECv%+sN(2YxDi+YzggvzDqwxl2p@ z#cSA&MT8CfDf4Q=h2O`wlx)toxtj11DskYu%=J3&J{0Ay>}$0dQL5SUcBIt0;dO!U zuyu2*&9G&2E0yc2p{#mI7c(b;@3M_@0#!6wLuzTpE`v|CRSVIZ2>b}VSzK=oq*T2m zjXvab1-3r;CsydryJ{#T^dmtG67_C zxwYhf6w@~u-A{`?Y~VZ0wUX?$=?Jjsb^keJHxhYW;CpPVoXBg~^yq|}flm3%Q>es& zKW`6uU87$Po@^(LLnRJ;pH;5|YBU|e+x^uET^9DwYSay{3;bEDdL8aut3X@=?h<;_ zq9#kB5(mD^HjUS!2>S?t%W{p@#%t}3MP3*90eF3!$vR)hBG8p_yN~)zr}7kl=}mS$ zZuP*=iPw5z+2N{lnbjTc-nw3LH?y1ap{oaeHhk&B`k}DeXQdc$ z6j55`ll4GZcwOMnneSmN>DzX+)6XbouQh;Bi32}q=43UOPXu#Ic>usTV|1f{@+g38 zsXt)#zyk-cn>Sv~tVPm?pG*YIE{*Eo-S1dE@N?k*%IlVsiQ8uE8iYOJiwGO|^HwA5 zQ2G%K<#*C-{`{~Hqr}=y7}K|GbPy3X@aN6+|JVH5;=k7g9(dq^2OfCffqxbJA5{kv UmE|y;vH$=807*qoM6N<$g76zli2wiq literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_388.png b/smartsoltech/static/qr_codes/request_388.png new file mode 100644 index 0000000000000000000000000000000000000000..fc891866dc196e132d6e255e6e9145837fc99014 GIT binary patch literal 1117 zcmV-j1fu(iP) zQHtX@5Qe{68~V|PK0uCQ->m5)?G5asaUVplmoH;b%X}T9e3Pu#~pXvamUZaB}WfzBCO+0M8=!I*25~2kJ#+g`Mj$;{%Sa? zs>-CQs-a6qFhrOFq@(&Vg-#n{dFp3({86~6E|4X)n7DvWRW+tla@Y^9I>*n%w;uf* zZ=wq~VI84Py)yslt2_P*c>nGHGKKfZq_j36JOQ<+n~`etjm>zgu#PG#nnQrJ_k z?)Z!0yHr6{btykASW2*nYR9f4jyxu6|wfovY6AyP{dmB_Rzqnx(MG zmFx}gOk-D_<99`^Z`A??414_z5i45cnb=k5_<^u>U8hZ!x|qzG#a%6$sTE^gb&lT` zRdsb-vlf7Aq?GhEV56R^&hdMr)FuKl=}nS1yh;~g6OK zsEf8b;KkN7$)~tq=lF447eM4(o24K4y3X+fVe7h0&`CiUBDzW!1rQth0EREo^uf)rr+#+FAB_)@+)J|cm`eh{ zP4ZeVbPC&>%3M9U7e7YqA6HIdS}?8CI?ExRrh_*u1y=_F{Q^&i5>}_$4`;u%ou;_^F@W@kimiiWqf2 zV%suo=e72+uj?E?5V{ZhZr|0p+mDzyAL|@Hh}U;@s%k`LKtD%Ny}qe_j=*|}ivY9cl_ya%V8IQ?H$gT%;rNlTIxJ-?Y<&@I#2SiAa3>W?XbN)O0uh%*5 jxZ{pH?zrQQ{}lW;l)+IaEwTSC00000NkvXXu0mjfvClnM literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_389.png b/smartsoltech/static/qr_codes/request_389.png new file mode 100644 index 0000000000000000000000000000000000000000..091213ad548916679ac775efd2af39a17f8e94ef GIT binary patch literal 1155 zcmV-}1bq96P) zQEKEk5Qe{63Hnin93V%LZ!kv+d!*dJK1v@TU_SSUG$w}(#Sst4i3{!j!z zRZ^*>h;oOG|J*}^;f5P-xZ#EyZn)vc;*!lH{VXE=EK*+pt1xz}z+67Hw!gm|*POl75q)+#(0}ZumLzqPn2K3=*$` zj=xq9VM4$y!~rBuFDNs#dF7`byWtPUM-dU}0B|aA*NYObo;0~*&f=7wRm!^dxZVvv z8J^@+-Ip@gr!^%_6c!*XWS@9g?}ncfFPW2+Gyxq#qcBy~1)?s=>#6F3>f|hQV)#8) zl5xu>DF9r~*8vbGr$ve76H}ex`zb5IFp66QR?)F96TasjyWx+*x848SN!!FWk#p&7`Z)VK+x<8E9^2-1 zPKBV5wjfx%#Op;NdlcqYucUw{2x6@)pTqT-rVYU>gnCcAQYe{Q0 zeCm|9yK2DIFGY3(*u2j0dn`Mx=E-d$to3!JptHtb^L2*bk2{rq_T*Z+*+V{~xE0yW zerql&{h_@Zek#1Ag>UMc^76H;FmhAtn}Y3#8Ge_w+o}^cadq34XqFUq+Wk= z(wgcF-)ZHvPBOPZ_!P|-ORQeU4$)H3>0y3Z7+<&Q&!--{;g7<<-PM@_X=$3uph$Uolj zr^Dr~L{ky*sOqP{?DJ}3>|Cj3{~NsOtSz0 literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_390.png b/smartsoltech/static/qr_codes/request_390.png new file mode 100644 index 0000000000000000000000000000000000000000..f4c6926607899deb425b9b3500fa9338d0695d43 GIT binary patch literal 1112 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 m>l}C7amO8Z+;PYM7x=$sa_X?P9llfm0000 z&5hhJ422&f0eh4?m{Q~pQc|!br31T^EnorrIDif2K>d05l#zqUz>kNC|2`-N2uhEn zyrSr^`9}{85GPKYIC0{{i4#8;mt-F4XK1fswo?xo*L-J0ILY% z;uKNuBID|Ts2cz{RaMm^-Z?t)i{U=~yADA74JcMX=MlhsyURi0?q0D10=Vs*(TNiW z0FhxA`K4Qmdh_5c2!;y9RR>7=HU~->Nfzp0Ac_7@U#E(#9tK8 zjuaHY3IJjA3hW*TfFLZ8bl0c(_q@@GUmBl9#FXo}zNw7sn<9R^DdL9*;)jQfa4I8q zldz|bPW)oH#k!+t5Fl*8JU~)#TLH|s4f^HL*M4{6&%$AOkhlOk+399SmN`LCRkfqd zuIUuElxvw@`rU~?3oo&5^RP7>0K{d0&bJMSzXfXXZ}kAeT@XLsR8AS4_%-ny>nz|o z)d@}!b+a25`chihHHl=q$5==FA*(a2&7lYzbP5}ihv}A|Tb#L`UE>T({BcV`3(jPM zPC?tFSi;;?eG-gy#Jem_pF#By=8omoDkQT1(d&qJm{zlZ7gUpmt&?l!Rt0Jpf6B&X_HhH8R%pEX%x^R*@E3Ydn? z9#-$>nV4Qj{87sq7VSnc*lFH8Q4~gPhGMKE-eFn87QLz^xD_|EpP*T}GS(6Av%Id$ z`MRmO*Lq^=3|c=S5rk6N8!YpOUe^NxBod|T_$>xe&OWslgWm#Dk72q(cB)b@zk zZbjR-GXXmPJZp5~*TfH9oha3Zyw*zrFC>|fv&qVQ9q}HkwTarddH5+>BTHIpSmGze zI&FJ7Yx?9%TRn=Amm7**v%;%&Snd%c zepakY29p$}wXXDXRwrZ!JMlBC|8PyaQ&W*`e61vn8S9Am;<0FmxTMe2>HF<20G#Uk z0Mu<{=Z{YOVtAXct9uVkL*!1Urk5SSp-TJG?@s)G!DS405xJ>~41i9nhm6>zYKVV0 zI`M1Z-#@{GKlO{Erk|jlM3t(3# z@jm>UhAn;TO_sRSVRM0u`8wh~cKo*g-x~jV9dY8si4!MIocRBO{{j9yWJ@X@0AK(B N002ovPDHLkV1jG&9L)d# literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_393.png b/smartsoltech/static/qr_codes/request_393.png new file mode 100644 index 0000000000000000000000000000000000000000..5815aaeda861611499c8a7c424dd36226e911081 GIT binary patch literal 1150 zcmV-^1cCdBP) zO>X2k422)Z25PASa)3IDe1kqxFh|M_?4#5H8jzO;Y_J!kBs;x}HArgwxG++7eV_{< zNbyICC{D=q&lwsZPMkP#;>3v)C*BqpmmVT_K;*uO3;-}m4@~z>?1DLeb!exZ_(k!k zs;UXl5u4~Z_hxYNt}6g^Dnq`gs_GFxsh#*m@!8#%ygz#YVFh9;9?mRLL`MK3(l^#l z{91Vb>9bA`g~aDgff-N$D)H%Gllak8J8|MBb6v=F9!UMK?(f>(PkVXdFM(%Y7Zkt@ zNK9|g>DTWb2nhmoE8>_RWdGMlJMl~7lZc4i{ieJ>Z)z*Nm;m#C03ZW4OJSR8Cw?*9 z%&EFB#atieL;_f08HV}9X4;8g6NlA7V(N0`#EnaVpsK1X5Op=Lr>ZMdQ>RvI8DILh z6aOyUtjVC95( zBRniND4g$iib+INb+NWsp1A{LDAnX2^76!A4Byx5V(ETa4W)J@j`b2|6U5KqyLBBr zn&v8T39eo_4(l$ZrPUE{fNvH}b)0Y6^`%Wbn*|^PeA3Cj(pEe1E8^1~@G-iuh{$6R zOpg_Lv>4u{Kv>}q8fqtgF&z8MRrh_cT0YLJxfRxeMOZWT(!ZVfcj3kAycyxc!`M&S zsUFgdU2m3FNBm2&^L1t1sb;Qq+{ArdE+5m^5kDcjD)Cs7*0D4r%;3t!A}p)K#M|JT z$PgAme2U0>0$`hB>$d;ghjp85s-5_y@ZBzK#e7piPDI6QW0P z9~SaJot5v9GuPtg=1H>u52pj`%6rc{ojVNmquPQgw&f*CBAy ziTEkWy$O^p*52gz3s6SuGO`k5^I4tN`0{(ddx;-!-X)9A9*85L(_;lYV#L2L zZgrCxT4ya-1ponV>U~&jJ*+`HzpWAzBP{VVBK+@l#EBCpPMkP#;{OZ$4*-1R7LsEL QK>z>%07*qoM6N<$g2)gl)&Kwi literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_394.png b/smartsoltech/static/qr_codes/request_394.png new file mode 100644 index 0000000000000000000000000000000000000000..e78b9a96419ee8cad9b2cdf47d7917dcafd406d8 GIT binary patch literal 1132 zcmV-y1e5!TP) z!Hw%U42D0h4CH77Q$R{lI+&6MucX(3T}ldAKt2YL!97s2oxD9ITFhik9*kt{4{`v4 zB7aI6QC_g=uUBYr+;PVpcieHu9e2DfF2y?JGK(-t$998hpxj`tk6zl1?)cGgR8^Iz zs;Vidj=h=zVRvKq$VQBB{o5V?F1&hO0%8hk7jw7-&}Vc6bnNx+u6v#1&sz8JU8nO+ zh~pym6;O$309YO${_dA|{7vyc9ck`h8j>;%A={tIr=Ze!bjOd0SFh_8m_cG1(CHI| zJ|Pe?aRiCiE-SOezeb}werS9W5s?9apz?L?AYMC4ayQqK_QGN%Y}3&lKNxQAw1qEa z-fk`eETWKsK2u_1v(X(tCcf6NK~+;NRjC(M%@8$P)Kk^WPDt?@*6|ncX;_5mtO_Ou zcj!2Gh)4&_CuKTk&pgd6*ee5FNn1ene@DWcunQS-lcqdR^uyp##k z0MP&42?)w803n-H7k_t1ymkn^T5;QEbjJ^kmsoeQFjw0WCBoJCr)pELrpBW?elUFP z!`7k!g1KI4$EMO7(~)5HtIf6Q)r8|u+e7!CSgX{{^|taA@b16k?eIlJ&KdnR0Q5JJ zFYEL#R$<7666UPnZ9BT-hr;)I-AK@y$W>W5s_ORD9@)%eo#Rj0mcCWnWZ|&Wi)+@0 ztHh2siggyvzzS6Jt8#a3hSj^(3Ek@)e+`ea^h-W1jxuC8ETrMj}Ty$UHF>l|-@FLF1LE~1(iA=ZmrD3?vS`!O%?_9Nl7W_q24xhfTpz^)@vG`uyr^Zl@nH^6mdEgx7!z7j>l ziz%pF2r8F8BbRs7bv=SHhn)p2dtXCl`b;V@ z4PqN$WBSO#{Gr6FK-~7kzV&Z+{JZd74ZGVEyRKy_d0m1!;j)UxKEpcxtm(b&8~?Bu z?N+_SS2{V~D%Jt)iiX;eFzdJ8gr8sMcq`l{%~X}Uuf(qBzu$^zdfm@}L5_Nr(&#;caWc73%3upm>^$QV+IqtaQjyvwS zO>W~z3`QSE0=z5%Ie?E+zCj-;$dUR6(ouYX21?5SWpEbtYj>|K4Loj<3n5PQP!>S2 z$d6P-lnu80vxNr34L96y!womwaKrb-CEJL|1acu?Sf-l*H-S~sCD~=a)eS!yj;gBS zRaG?%sxyPC1^|Zi2Yl#%>WKNRpWX0R<7*CI@~PiBkof@mHGzIjH({Cbts*k+yt?7X z!pDct$~vK}Lxh#&dg8-`E4Y7tUQIWhb> zOI`=X;nJ2$R_@Y0J`9>-oj0#Dd^?`JPG_e%)>TWvZ3e)_8Un_@9zgVwMYl`<7f>I7OI$S z{ByZC+j70K>*i*x#X7^Ev%4C$wf195=}Hb)l@qM{Z}@Jwi-?>fa#=<6OGe}~x#LZe zO6;#=E-v!)(~hefek{C?b#u~7pcSo6G-*{wXBO)Wf6BVNuBCK&+z!Y+|CZcg%8B7S z>2>iMi`O+;6T;xoeWLd7a_UThi;qE5LfvR3`ZAh%OTX z49ar;7G2J9gmnTR>U`&0KfB?t!te9CSj4z84A8YIfU*f&AJ*_a@MXG*&g)6ReT&FB z!g7uz(PWt@uIE(c;^G6oadpEFhIiFOClJ?YR;r15OMoV%SgbSrIqP+}R5T3z;L{(6 z>;l*hYxo8$c^&li>hCirs;x`rOeHpaljT_FihPn{m}?{Jd0%al#-aq z(-IDA;bC59`15#^MdUNoLE*KYI8n{3Dy$=N*>82jkA`<|VbfkutnVn6Tk7U&ZzdYP z8(z~loy$8C>6pZPy3VPqVaW%e?6KYVs`EOP?{0R8tp|5GG*oP_Yp_-3hpU~yUFVSTRD&6gG{p^On3V%GS zQ{grOLloSvQT)#j6`UgeIwC%RF6U?`P8hzyvezvsfDH)LLrm6FdS!y-iB1vLk0>}0 wKku-*;m5?q{(GI_h8u3U;f5P-_+Nql3x#zgMmpU}ApigX07*qoM6N<$f&eT#x&QzG literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_396.png b/smartsoltech/static/qr_codes/request_396.png new file mode 100644 index 0000000000000000000000000000000000000000..43b8d00063d84d73d393c888cb4d5851173b57ec GIT binary patch literal 1144 zcmV-;1c&>HP) zO>X2k3`QTv0KoWcsT;`40%UL&`mJPF_8?tja#5(neozb$q)2{N zL^)vVKSyXV+;GDUH{5W;4LAH;T(UV}6Ooxc{Q@=z>$LY*MMPviZ*{{jihEU64InZB z>jd}!thYz@Fs}~*231wnXZ+ymhF=ula`@6^jHuon`gQM&_`8Gk7M%bn8}xnUw|;iRe;8jyL}UW_3?TF7fGzLl@b?eJhe4$)Zckj@ z@QdN-7hAe(L-IOZ#t4kD)Vl5Fw|;iRe+o}thYv&gP}K;&eCRT&!l>E*(#;w%uQU9B zb&j-*k>Y=#8puBaDa@r&A#`3T|bGS1V{tn?`qhu8@bdVex6M%&+QY7b%wuWt%fZfkw|Hpkb8KH zWpa@+v3Z^0XW(8{rDZ6mwalS z2Uw?&#q0jhFHKXj_4Y8Oli^3KO~hLFx9!}hN|SCPVHwu&V|dlq#iwCdHwSC`x_+-` zofE?kSP5=*<_dWaSEJrHkzFvQli`Of2Q7x$KA|R8pcfRE`_xpOh99%ybwE|Cw`kUc zC)wf3^xtBg;Ro!ge2A1ZJ5(J?EO(CjEOIxmGyGL+88*)*pqt3HfR{@OiUiLxtl_U) zpJAH>pbfqPw5uuMHZ!j?{B=By`~CexMW#KsfY%A=#OrBGw@W(|6!-fDa|VEjB@(jqQ#k?M#*=+*H%ib*t24Ptwty=dNz}Me#IR4HWS(fDgNfOuOhZ zJ|z2EJs#l9)eXNGUe7t995&I~ciMC)v44ZHPH8Q}8h#3{%O)b9VHf>9)gxi2L1o@V zT3svif3dpZ*TBD>)yWuLeo^P{lG0PyT-02*?heLSu(y78!+#3zl}_CptWE!cFReP$ zoEUzN*JT^}7sZ;$uFhezS(n)GLnij$>kK#CaKjBZ+;GGH7x=$!XBL+uYOV?Z0000< KMNUMnLSTXsA2$L3 literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_397.png b/smartsoltech/static/qr_codes/request_397.png new file mode 100644 index 0000000000000000000000000000000000000000..c948f27dcdf388d6802afeea3e233248c4b7f661 GIT binary patch literal 1092 zcmV-K1iSl*P) zOOB&R5Qe`PkZPGoa{wO&-(b#EN17YJQG9@wU}*^yv&aW&SN8^JReSu$!Ucv;X{29~ z8IPpQIbh>oM`#c(T)1%I!i5VLelBjw+IR$W3!|BtbpWjK$gXp~^?Kgu!ru+Y-QDTk z-F<4D-WSqGK7G2SIvrm6*@b@>-lo5E2mQa`<vM2^jzR0nF_JtOnuy(S^S!o>dndn9I>N zn}!KXS6iI9Ou}c3F8n?56e=WZJjD>d{>Zl~nh?I*qOW@>i>(G>fw9AqbDM$jvfxj* zzV@>V|1LbIMJDhepZWkPb3(`|6++6U_z)KPI^jnw&9Gr1stL0GhLGjxQ@K5Ci9D%J z_+HC7-v#2juDHHrOIi9go|TwV#ZsN{eU|hyK~mUM=GqCe93f4!Y~>57PWWC+PODnJ zm1SN?g)bnj>!L6Rj?PC3K!sx=^6R&+;YEOS`S^t_PuCB`03EyS8+yyBQJVCB` zJ%qI6Dy^ak;b+xhOMSKM$DvBvrK{;XO6dF2&o2DC@!8@U&aSM+XlCwyH~PF~BDJNk zn!7L9^~}+QzZYKBCbmwKy1q}{__U>zwr9Z+QdbFO zXHKOxfNBSsR406w`J-*c*wjH6$_2<U@|MITR z(#F2MSR(tsvPWALG2zE7scwR&HsaL5{wTO;LH%{Y&&2H-?#9@y#@K-mbDO@4N#kld z{tcrGe-Hd8Rj$VAeQoK7HNG`5ewSXDxVFx0Cyg%rJ@GFuSdSUut>%?CVCM<9Eb}zO z3g2zdG3>UQ8@3!u$dwBo3lvhF@I7Yw?{&h33l}b2xNzbB3;aLan^G2j3bR%K0000< KMNUMnLSTZw)->k; literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_398.png b/smartsoltech/static/qr_codes/request_398.png new file mode 100644 index 0000000000000000000000000000000000000000..97fd34e2a306742d022bd810a8ac32568ada5925 GIT binary patch literal 1093 zcmV-L1iJf)P) zO>W~j5QSfj1Y}78bATL0x|xw9%?+fZ_y7&a%LZh;Srm(;x_dT~yAzLJEri(82g<+$ z>yKoNIAP0QXJ|mUaN)v*3l}b2_+xR)*28Q7uvib^)&q-~`31NeaEnK$$Bi!hMe&g& zxdNPTJ%IGxunhTzUDl3f_C}k~ktDgtPmV79Me$pnzHCYxFs^`IRshQY@ME|e=RnM? zfAHwSUmGW{J#4y#uB!h2#OT6b6kpyqV0kCq!}@na_a9}wFZS}np96fbK>v+(e+?miKIH7+DKU}Vl~Np8rVSRPjRVPm!s zSGJCv5jn)TcJ#S!bkzY;o$wRpnwwLp5|=vg=pO;VlZ%+<07!Mh&sb!nTmH)x2ILuT zT!H3-#GK($suOO{S6 z-Y>1od4=XW;pgxizUA}l+{1nhh(PZ8R`S{n$OoW2Zgk-&`NF8mQ?>&~GgN^e8Mi(v|0PM2f4db=A^eP){(GHp;lhOr7cN}*{{sIPA2M^6&P7A900000 LNkvXXu0mjfKY$&B literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_399.png b/smartsoltech/static/qr_codes/request_399.png new file mode 100644 index 0000000000000000000000000000000000000000..1ed790e633df4ab9d2c26833a18ffc158f349335 GIT binary patch literal 1121 zcmV-n1fKheP) zON!%25Qe`P32G@p9iWaP-C&MX^pW}o(oyOF4XLF;;-5vnWP64IOHH+L#G;TZ^CK+? zBIA{569;7e>j({wJMOsSjyvwSUVeiyYVHPuOR@#*PCE@lUWa%NTx47nYAac z?)Yor?agP+)~p5?gMi^@yE14qW;=g%#~lZ-vAbB@YiBb{W^Q>CbSpOg-qjs{4LsYr zPQU^JWONr}`1!sX-Nghen*VN8rku38<1dZRW;t?Q+U(ase6n$AvCpp-8`)wAd+O?r zzZf2ET{T}~0nHy5gKkAEn=$tdz-GF(bl?5u9e+~1WKP!nk1nN37;=In#q;PVrbNpecIp3WPQ%)Ld>Q<5^j7pdXT@(zn@zm8Fel}YrveTBs zhbUcnB5$)%69aL>b**#!fb47eKyu_l6F)|muEel8q-ebQ@Av^J`MRwY-LKY$fNbtD zhVZ@`OHazuE$=II0Rv2@tnT=0;#Zjy8cBiZ(&gM-ld^fyxaC0BZJpx>}X&9HXdH+}1h%sO)MJ zF{H>Rb8@Jfb!|{7)p|7H_%YdgbJb}JKx}s^0|2pxL01wfPyOzWe-}>GwPfZ(&fHD+ z8}6=N>ssgd%+kXE(vX&=buq_JzAY3*4&JS#bFQ_Gy(ruikNu}6cTGz^E&GRjdB>j=U)pT-u1;Y~p^=RgZ|=+N-|&O0 zJN{buZGT-#(1m?lKs_TC5wA@+ehj}2RUxN}YtmTKy2}kyoj}(*#~+e?s7ftMln%PC z_5n1dUglco_#sKDk{G^by-FomcIUz3>}cycKO^S&8F;y?6F>@^>BonpAJ)R$=fh+1 znqrS(9X}VJd$5s4_W9L9+;tbTbj4V1e6sPktnTE`u8V1u?cTDQ6X zg+Y@Gu}}T(j(-<^>(|xVL>=AVGvReu$B*OpF>JZ?e`0_4iLOuUcr@Yo<6`>%IsYyG n>vfJh?zrQQJMOsSe+vE&N`YHzO*0lp00000NkvXXu0mjfojot~ literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_400.png b/smartsoltech/static/qr_codes/request_400.png new file mode 100644 index 0000000000000000000000000000000000000000..c4171525d47085f8f3b895e72b86f661b674bb8c GIT binary patch literal 1161 zcmV;41a|w0P) zU5=|b5Jpc8NO=UQ7m%gE4thyfcS*AYyp$}UC3tKJ^v#29Oma0EDKJV$R6TS<%#njs zsy~+<6FVgQwTA}B9e3Pu#~pXvamSCvElG{_lNq4}>!%t*yR5fnFy%-4<7RjKYy<~xRP3ZIqoBS+2d_^I(=W@ar|KV3w3yCmI;S5uAs zy46_E5>wbiXLtN$c(irJe2Hl>!u8t(bM&wZZ3VEH?k(M`zr5pbiX%y))0{tOl+9cm zkYXXFjCNxh)$rEu?)a@q+6ZJ zcRh<)-$;b3VwiXA?2excPew~4(ah0}RrH}6qBpJXMxzm&-NQP*M>blgu}Us=fb2*| zl7_|jFF)d1=lBlEL0hGiD&+Jbsoq#^qrQ73bggszIoa5-f$T^jn=~L^_-3WZkgTidVN9qZu*4bja+EpBXo6E2R!PDp}8BgzF4U7g^uT z==U|-y0!b{XMB0b-wt21iAoxpRF;G2O)HhFJRp($uX|X>pOu^#tU+6h;gpMZn?;K? zoA9{K@dI${*Bmz0i_K!15!&QZrCUub6(2pj<7dM+m6KGj8?%K=rQ&&0$lI*Qx~+5k zd3mh<#-MHFu1Y+z@xS?D*E+|al}%iyv5KieF3_cBl(HC+i^g6hc6^s4Tc_>n!&d*Y zU5gK|d98a`$9G6shmDdVx3msc+MQwx-r5Y{TIcu<*=pUo7&gErt}7`;?&|co&hcGR zJS-)oE7`=5S7b~1xO54));a#1XqAU{lg*;VY7Vphxvg`2KW^48mV1PAzOW9Y(d>Vr z`Sx>89N!~3L0#*0&1&JsYU6rKyPfB-jvs|DW@Z;bJkx3IIRT_G+q!U_(U7-R{FpEA z_{m`RQkv`gVIAKkf1K4B+G@_5CtA{3ol^_2 z)VWIh<@+Wa-y^9&Jd(>IB~@sY8t;ZR*GS@Vo#V&i@xZ#p(g74e>@POEZ1&#z-5q}w{&-d=Of3rS7Yc1UtxilI0+w3c z?IPRYZ~g9$zZfrPb=q~_j>my(IwscoX5CP6;Ovf{3^)DvGyg9B>vfJh?zrQQJMOsS bKL!5>m8k`WhkIlr00000NkvXXu0mjfC<{z5 literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_401.png b/smartsoltech/static/qr_codes/request_401.png new file mode 100644 index 0000000000000000000000000000000000000000..3500aa002c4516ddf6674dc1fca0b5f8900e3584 GIT binary patch literal 1154 zcmV-|1bzF7P) zU5=|b5QR?-Nc{*>FMy>uJBxZrvjbR47H}o=*pj0&4`qYtJEJQFMhVKP2Sf~?3{t7e z^2?GX*FNOe7E(GN4vBfwqEws?=Jkgc(!J<8K!|W8xqV0l4JL60PdcuS zFZ^^kJpDETRniV2HspxLQ*{Wjq1(E^1Tr@Co5xeXyYOe>u63T98_UlhV?dX{u}g4G z1f+GscS%vQtXDoZb}3u9z=UG(uw13IPWT=vcC8`leigYaLHDL8u9rD!moG@`gg-2+ zHw8Mn>g6+E@a5ca_O;k}VriZ5U3f$Cmh*7rt%X^Cw;V%6cp!mgNoSWsXBYmixY@ue z8%N$gh;Xy4dO$IFQ-4>MSoi^Wm%wpuvr0|<-OPq>vr7qD&H7S@4a@rPMIK)G$?y`x z#)j)zPRlJW72VbdDqko30NiZ&_UZ%R#R$MVhy%+7k89(m1@9#uUiew@aQh&pA)!?I zb6LXMoxC&%jcX?Rhk4sgD_2pYvR4ONkOR5+E zN|j9OI^p|qyT*p4s{~a;F)+8ewb+A;F8vF>b9UkHhA+Lu2?Xw~g$M$3n|#Xzx>Uvh zaI%Jm?pJ9yKJ~i`e->V6PI7D0QUc3uoGc5uRHy3XVTC^~rK*oguj;diO*4SU6{`LV z-z8P`KPy)WB-T2ZN3Id-uM>U9k$VL9OzivHn2_!mYPK580HD8yToRGWKtDrTM z1YPdKqq;hU?~;-PUd)#dm+EUBK9qeETGt8RhnHw#Q;}FBhdfqxCT35pb)E2iQe{r+ zCX?E)R!W%rJLO@8?~-EDO1Xb2kZmH2wN#608-=t^_+!GYR9~_iOQ^bR`{x=`$kqwp zA?xxDz$Q!LkpocgObl@eGo*FGAC+8(4I==|pCFJxpdqF{(n9=9mcMS2+7fl#OZoQH z?=JjV__j9D)C)P3cr~}yty$vonONC6;RoTf8Kxc}<2`>h_IfMd8CwbzcKLs17ygd8 zU76tf5hrUwGH;{sEZx*Mtefm!>*0l;1piqPs~u_ev6DJgR~)W9tnddVhXs=xv<3#i z`#XX8gO~>Yeq9T6gkkj3|9sDXi~hY%xNzaZg$oxh{8jLO0K zU5ev65QR@&8S*GY7LcXLJD4RkcS*eidns8!gZ$VaQ}ZB|C8rq%VnZhQ)I)dt^PvtD zRjN~xS`<5M`fm>n5GPKYIC0{{i4#8-mtq}cm^)zV7XjuDm_+PTzGtrv$Bj<>Y&cX^ z6+u;1qbs#V&;%WQLVhs9sj4O*M5hfgzV&w}{%U--@D(%xfYUa@`2-mN=mLH zJIH_~m#~M9PW)te_O2Sf6!RjOZr`Fn${ALt-T}ZOx{Y+N{^NUE<&z?i zAVjoJLjj0P|`DFLJW|b~0bR&v#Qp7!a9r3-mPXJ~Sgyb;NgAtDNLZs~kq4nbPG7qs;oas+0IG zt1E-s+SH<+33&;%%mu(|g7^XWBpvGFVfnb1%aUg2OWT$Rap9U1;(M%yv^LGI4T>Vr zJ>*~Nb;NgBlVPg`OS8rGHp$f*6!bdc&svFfa3$b1MFX5Ro5BD<$NC< z?TMu$TbDbPF2yRT(CdglZzWZthP1NCq|WO~4QrBKjeqny;?J2?6Q&L8wuY$pMxa^g z#8^jshiz)u?K%Lho~Swg)ushw9r4|GxL*|EE@IkTF_C@|5jy~&@y;VhCw?-#&9Hev zC!9_5qSdRgd)BXI4NH8N{jr9v8eX%4J$olRV#IgZy7&L9Gv8YT@G&o_Q_R;?jy=iy zv4wm8i659@QKaH+f8Uo4uuV*)azcC`zV4eSwpq}$Dkss}5<#ig5kCm8XLaUMVY-UE`p$d zgt(LkQ~w1CpI39oxBl+LUxh!O!ETDM>d$6udeo4aVTtd->sg&;+pE$jyQ4R#EBCpPW)fNe*-j26+J@HvXKA)002ovPDHLkV1lNb BB_sd< literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_403.png b/smartsoltech/static/qr_codes/request_403.png new file mode 100644 index 0000000000000000000000000000000000000000..36ba84828a6c5f1e3570ad614b7d80acbdf75951 GIT binary patch literal 1135 zcmV-#1d#iQP) zL5{OH5QSe2NLdgaNOv^Pm1>>$r&I? znq42pFKdB*ZU~^^c1DtX#&?b`{G|AjrmtQ)0ngxU3BfIre6Ji736y z7|=ulej^eKP1v4O@EmJD`rU=U7f-XNS#|!^B+yy#v zZU_Vt{S2>MIl4-REZT(#^o;O_dy*VK`rU=U3ol-WuA%deHnD5H#gzv*` zKtoK|M~XlOS^pwGpHR~Vk*9XGo0v*D>YovsnUav}P;1A4A45FSP>9dZppcy-aw zYgSi2`rU=U3$IjSLzrRxNEpJuAm9Nvn!6sF2w*i%L!&;d@IB_e{8T06M6RTC97DeA zd0pxLE3Xs&x+NdVRjT)4Q#IQ#w`FsK)@u!~X61FlU$xEad~##aMqDZ>?)W^{xykE< zzhu>1=hGLGa<@%xz>|<7FdR@uu$Ot6S4lWDV56|%6Dz6j1!=C24SaP_O(xn`3 zevYd_UMGB)Rdd~zw2gkR#9HRIL@6%hb;5Vpri0{Y+EhYHIxAte%!Kkf;d^m@`Bz|< zRJl$aO24A@Ka=Z)m~R|6y705%PZ750aOG>UlW3OQ~*9kuY4-qyjW;TQf^4xA#ax4k;Qe{o&*uXDYwIvh8;@U!97nv-o+UD?y5mQ=Qs4*G6F z_&!TsH>2KXVq01_Vv~i-N)xHX!jHyRb6KvRSF-_Wug(;InPROCKQy}V6XJFwNoH-B zWNF3*GAYONPmM189QdDkU0G0EHDk9ROj3PV;fM4lF!_Ym_)aEF8`fQz7oMyw5D3Ha zceH*6)SD3gx|Md zU5czo5JpdoLOoj03+Sa-JLn}fcW1hkTEGQ;EKt6A$P80^?l7R$)HFss6kX^cOZbT2 zOxwf(>;F1JL*Ri29(dq^2OfCf&&4fUjoro?v+Hc>dT%wrZ1mUJVDwvW&s#n4lj5x; zX#ik0>3&g?UaJYajThN1-C0SJw8amu9{5S|(cM>n1^V}g!FUn<74+-Y>DyNi{G7Pi6=?5f^j4z|up5) z2!h$5nQAe*-$o;{*SpIH?cPYAF>OZ;Q0)fKX|eDSeeBb&!e+zb{l5_+Cr$$qizX;M7q`8Y-!4CbB1N zq;hkpF7N}ECk@R+R#@uSW&P0(RhHSJKmRLK7x-TDyl$PorD&Rh>wwS8w207&P+j2r z%#*fimB{5ZFMW8JrTK>lLv?}gvy~6)z+))ukecrs7GkKv*9CsSyk9rYCYk|be3P}B zYikE&`RWyGyQxKVa^|JbhbQb?JM_>$*}+L|zy8bMR^jv$L7K=jlV*)!8)@_Bnvv8tISt z!PNsl74CT*)hf(__lt{%^GFQ&YWTXqciWfQL~anLW^f6q>&`Ke*9CqI-_BvzO}o6m z#CHUwY8IB%FH{%!Zu8j$S!?a!zOGxMt`@;5=CFZ35wE0Qe)cOJo}hUceLAC4&M4Nv z7-z%+KV+p}=P`6M8(X%U*h5%MYYu@Bk_N_OIPJi^X2mUI2wX1XO;arKEolccU z;;3N*KW5$~_5lUO;Wc>}kyE;1eX1f<7x)wK*}NI|Fxp|ZT)wUbwB%P&e8cL2p9){k zVYj}n`W^>(M?>-?nv?V`zYGB#8f z_%2)3u;mm^saKQMHeF(Gq=f1M-)kOMVIwnd%cUOPaz-17ye{yk%tm`(hWulV z-KgB_H4}FGmem741zvyoE|^iSW@n=nSgW~CxnF<%jX~vZ??*p-;IG2JzN-_)H_?Cm zUcJ~(jBf(wT8tO18+JeX*#mzS{)ZZNvzNUC${g0KiKt-%KVqi;zUSX9{(D{Efd?LV g;DHAo`2Pj}8?fzYzu)WiS^xk507*qoM6N<$g0f^d)c^nh literal 0 HcmV?d00001 diff --git a/smartsoltech/static/qr_codes/request_405.png b/smartsoltech/static/qr_codes/request_405.png new file mode 100644 index 0000000000000000000000000000000000000000..00dfff9e05526366f49e50bba02251e9d28664ae GIT binary patch literal 1169 zcmV;C1aA9@P) z!HwfO42C~G8^}=srht@Ucd#Wbrlje>E+qvlU>^g>;5$&XoHw`F51DMpLy(O9K{h~; z`bkM6$_^X<*+WC%fd?LV;DHAoc;Lt4QmjSf3^0o@N(;=b-6%ba!0fm7$BiENo8q0S zs!pH-07+H)bQ9@Q=Fa~bRaMn{eCOzazZqU48S@#sF94QS#~u_=#`A=9(+4`9%dG-U zK4$d50|$^Epqmq$i}xwswx<9QKC`n|UI!yZ2H*T6l) zCIw~y7NPqp0ZyUGQa%>DdFy*G{qBK386QQY$X6P*k8WyIeosI*0n8@_7L%}tjvn}% z;pn|VQdM1(D=9;#86A>p(YmV*Fa7R;KNpuCkbV}SyNZZha&gDOB3z>|i|D7vMCp$k zJ@9wK&AI3%ESl-yf72mlN)6A1M5C&jF+N9;p|^v9*|OTT;I&&90|Hp)q@8Qae-(x;o~ zkTQ^NUaw0x*=miS@bH1Z9DbK!Q?^8^I{D>pYSdjX7w@b>HZpABJMi(`sOt4(Gq>u0 z<*vD1TNRBmN{jRdjvn}%;j1>t8#QZHI!w|Qg;6A}SMDO#1-`?o*ST}K>sizTO67Rt zote;+%zo)pw?Bw>jHnwir0b9+)}CBRZlc=VH#p$+Zzk73;ZFg zUbl&LYi-27ZRUD_&+x+Q0)N!jDu}lwrs`|;C*M+UcwOL+o5wnDcMW)fuDdJbK`rD( zh7Ek5ZNi)_ElH}LVcpHv__qy=;dO!U#uq8IVcRINSTjuIToi`LoqJ@B`} zOROu)O`v8|ui;tD0R!>#Ang#ZcjOfj?xvWQiuzT~Eq* z$=F(^Q5t3Zm0KY}t(1t=%;`C84n-$%i&(H zTSe=z&g<}mTUHe(-7W!$d0pU-o7X{neN$Ol=e>!+t0|k6b{mE9((fMlv+!+iq6*nk zFRq8})cB_w-T%N3QWNtTNRu6+qxKU_S16!jSAPMpw0g+sfxj~@at0md7CS^tE^A1; zwn)z+MO>_h?excu9{9WA-}e3&`LOPwur4i7D#!Jf$gqJwXudPitei_{8Md1~{6gJ| zIDh1**9Cr*hV@R@0Nkx0&Kq&DsiB014g7KQyvp{#I@WcYWqVFt?gTD#!|MV+2rsLO zuP2p$Zf$3F?N?aT`@F=t#DVX!|HL}2=jW8#T#0q{nC!9+AYxtMd-3E_wVt=$O^Yy| z%aO#zW)a5AE&8y5@35jxM{}bF={$KV^M}HGQYmeT$%@88T91i+>30wOS-8Z1uM0fz jzyl9F@W2EAEAW2-cKG+SHVmbO00000NkvXXu0mjfuM -

- - \ No newline at end of file diff --git a/smartsoltech/web/templates/web/modal_order_form_old.html b/smartsoltech/web/templates/web/modal_order_form_old.html deleted file mode 100644 index ef8083a..0000000 --- a/smartsoltech/web/templates/web/modal_order_form_old.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - Модальное окно для заявки на услугу - - - - - - - - - - - - \ No newline at end of file diff --git a/smartsoltech/web/templates/web/service_detail.html b/smartsoltech/web/templates/web/service_detail.html index c0874f0..d249c32 100644 --- a/smartsoltech/web/templates/web/service_detail.html +++ b/smartsoltech/web/templates/web/service_detail.html @@ -20,6 +20,7 @@ + {% include "web/modal_order_form.html" %}
@@ -78,174 +79,10 @@
- - - - + + + + + {% endblock %} diff --git a/smartsoltech/web/urls.py b/smartsoltech/web/urls.py index 2ad5386..20a3747 100644 --- a/smartsoltech/web/urls.py +++ b/smartsoltech/web/urls.py @@ -17,12 +17,12 @@ urlpatterns = [ path('service/request_status//', views.request_status, name='request_status'), path('service/request//', views.create_service_request, name='create_service_request'), path('complete_registration//', views.complete_registration, name='complete_registration'), - path('complete_registration/', views.complete_registration_basic, name='complete_registration_basic'), - path('service/check_service_request_data/', views.check_service_request_data, name='check_service_request_data'), - path('client/orders/', views.client_orders, name='client_orders'), - path('order//', views.order_detail, name='order_detail'), + # path('complete_registration/', views.complete_registration_basic, name='complete_registration_basic'), + # path('service/check_service_request_data/', views.check_service_request_data, name='check_service_request_data'), + # path('client/orders/', views.client_orders, name='client_orders'), + # path('order//', views.order_detail, name='order_detail'), path('service/send_telegram_notification/', views.send_telegram_notification, name='send_telegram_notification'), - path('service/create_request/', views.create_service_request_basic, name='create_service_request_basic'), + # path('service/create_request/', views.create_service_request_basic, name='create_service_request_basic'), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/smartsoltech/web/views.py b/smartsoltech/web/views.py index 4ef5690..84c78f6 100644 --- a/smartsoltech/web/views.py +++ b/smartsoltech/web/views.py @@ -9,7 +9,7 @@ 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.utils.crypto import get_random_string from django.contrib.auth.models import User from decouple import config from django.urls import reverse @@ -21,13 +21,16 @@ import hashlib import json from django.views.decorators.csrf import csrf_exempt import logging +from django.db import transaction, IntegrityError +from django.db.models import Q logger = logging.getLogger(__name__) -# sens + +# Initialize Telegram Bot try: bot = TelegramBot() except Exception as e: - print (e) + logger.error(f"Failed to initialize Telegram bot: {str(e)}") def home(request): services = Service.objects.all() @@ -69,21 +72,18 @@ def about_view(request): def create_service_request(request, service_id): if request.method == 'POST': try: - # Извлечение данных из запроса data = json.loads(request.body) client_email = data.get('client_email') client_phone = data.get('client_phone') client_name = data.get('client_name') - # Проверка на наличие всех необходимых данных if not all([client_email, client_phone, client_name]): return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены'}, status=400) - # Получение услуги service = get_object_or_404(Service, pk=service_id) - # Создаем или получаем клиента - client, created = Client.objects.get_or_create( + # Проверяем наличие клиента по email (так как email должен быть уникальным) + client, client_created = Client.objects.get_or_create( email=client_email, defaults={ 'first_name': client_name.split()[0] if client_name else "", @@ -92,27 +92,28 @@ def create_service_request(request, service_id): } ) - # Обновляем данные клиента, если он уже существовал - if not created: + # Обновляем данные клиента, если он уже существовал (например, телефон или имя изменились) + if not client_created: client.first_name = client_name.split()[0] client.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" client.phone_number = client_phone client.save() - # Проверяем, есть ли у клиента уже активная заявка - existing_requests = ServiceRequest.objects.filter(client=client, service=service, chat_id__isnull=True) + # Проверяем наличие заявки на эту же услугу, не завершенной и не подтвержденной + existing_requests = ServiceRequest.objects.filter(client=client, service=service, is_verified=False) if existing_requests.exists(): return JsonResponse({ 'status': 'existing_request', 'message': 'У вас уже есть активная заявка на данную услугу. Пожалуйста, проверьте ваш Telegram для завершения процесса.' }) - # Создание новой заявки на услугу + # Создаем новую заявку для клиента token = uuid.uuid4().hex service_request = ServiceRequest.objects.create( service=service, client=client, - token=token + token=token, + is_verified=False ) return JsonResponse({ @@ -122,94 +123,8 @@ def create_service_request(request, service_id): }) except json.JSONDecodeError: + logger.error("Invalid JSON format") return JsonResponse({'status': 'error', 'message': 'Неверный формат данных'}, status=400) - - return JsonResponse({'status': 'error', 'message': 'Метод запроса должен быть POST'}, status=405) - -def create_service_request_basic(request): - if request.method == 'POST': - try: - # Извлечение данных из тела запроса - data = json.loads(request.body) - client_email = data.get('client_email') - client_phone = data.get('client_phone') - client_name = data.get('client_name') - service_id = data.get('service_id') - description = data.get('description') - - # Проверка на наличие всех необходимых данных - if not all([client_email, client_phone, client_name, service_id, description]): - return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены'}, status=400) - - # Получаем услугу по ID - service = get_object_or_404(Service, pk=service_id) - - # Проверка на существование активной заявки для клиента на данную услугу - existing_requests = ServiceRequest.objects.filter(client__email=client_email, service=service, chat_id__isnull=True) - if existing_requests.exists(): - return JsonResponse({ - 'status': 'existing_request', - 'message': 'У вас уже есть активная заявка на данную услугу. Пожалуйста, проверьте ваш Telegram для завершения процесса.' - }) - - # Создаем или получаем клиента - user, created = User.objects.get_or_create( - username=f"{client_email.split('@')[0]}_{get_random_string(5)}", - defaults={"email": client_email} - ) - - # Обновляем данные пользователя, если он уже существовал - 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.save() - - # Создаем или получаем объект клиента - client, _ = Client.objects.get_or_create( - email=client_email, - defaults={ - 'user': user, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'phone_number': client_phone, - } - ) - - # Создаем заявку на услугу - token = uuid.uuid4().hex - service_request = ServiceRequest.objects.create( - service=service, - client=client, - token=token - ) - - # Создаем заказ на основе заявки - order = Order.objects.create( - service_request=service_request, - client=client, - service=service, - message=description, - status="pending" - ) - - # Отправляем уведомление в Telegram, если chat_id у клиента заполнен - if client.chat_id: - # Предполагается, что bot.send_telegram_message() уже настроен - bot.send_telegram_message( - client.chat_id, - f"Ваш заказ на услугу '{service.name}' был успешно создан. Пожалуйста, завершите процесс регистрации в Telegram." - ) - - return JsonResponse({ - 'status': 'success', - 'message': 'Заявка успешно создана. Пожалуйста, проверьте ваш Telegram для подтверждения.', - 'service_request_id': service_request.id, - }) - - except json.JSONDecodeError: - return JsonResponse({'status': 'error', 'message': 'Неверный формат данных'}, status=400) - except Exception as e: - return JsonResponse({'status': 'error', 'message': str(e)}, status=500) - return JsonResponse({'status': 'error', 'message': 'Метод запроса должен быть POST'}, status=405) def generate_qr_code(request, service_id): @@ -220,62 +135,66 @@ def generate_qr_code(request, service_id): client_phone = data.get('client_phone') client_name = data.get('client_name') - # Проверка на наличие всех необходимых данных if not all([client_email, client_phone, client_name]): - logger.error("Не все поля заполнены.") + logger.error("Все поля должны быть заполнены") return JsonResponse({'error': 'Все поля должны быть заполнены'}, status=400) - except json.JSONDecodeError as e: - logger.error(f"Ошибка JSONDecodeError: {str(e)}") - return JsonResponse({'error': 'Неверный формат данных'}, status=400) + # Используем транзакцию для предотвращения конкурентного создания дубликатов + with transaction.atomic(): + user, user_created = User.objects.select_for_update().get_or_create( + email=client_email, + defaults={ + "username": f"{client_email.split('@')[0]}_{get_random_string(5)}", + "first_name": client_name.split()[0] if client_name else "", + "last_name": client_name.split()[-1] if len(client_name.split()) > 1 else "" + } + ) + if not user_created: + # Обновляем информацию о пользователе, если он уже существует + 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.save() - # Создание или получение клиента - try: - user, created = User.objects.get_or_create( - username=f"{client_email.split('@')[0]}_{get_random_string(5)}", - defaults={"email": client_email} - ) - 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.save() + client, client_created = Client.objects.select_for_update().get_or_create( + email=client_email, + defaults={ + 'user': user, + 'first_name': user.first_name, + 'last_name': user.last_name, + 'phone_number': client_phone + } + ) - client, _ = Client.objects.get_or_create( - email=client_email, - defaults={ - 'user': user, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'phone_number': client_phone - } - ) - except Exception as e: - logger.error(f"Ошибка при создании или получении клиента: {str(e)}") - return JsonResponse({'error': f'Ошибка при создании клиента: {str(e)}'}, status=500) + if not client_created: + # Обновляем информацию о клиенте, если он уже существует + client.first_name = user.first_name + client.last_name = user.last_name + client.phone_number = client_phone + client.save() - # Создание новой заявки на услугу - try: + # Проверка на существование активной заявки service = get_object_or_404(Service, pk=service_id) - token = uuid.uuid4().hex + existing_requests = ServiceRequest.objects.filter(client=client, service=service, is_verified=False) + if existing_requests.exists(): + return JsonResponse({ + 'status': 'existing_request', + 'message': 'У вас уже есть активная заявка на данную услугу. Пожалуйста, проверьте ваш Telegram для завершения процесса.' + }) + # Создаем новую заявку на услугу + token = uuid.uuid4().hex service_request = ServiceRequest.objects.create( service=service, client=client, - token=token + token=token, + is_verified=False ) - except Exception as e: - logger.error(f"Ошибка при создании заявки: {str(e)}") - return JsonResponse({'error': f'Ошибка при создании заявки: {str(e)}'}, status=500) + logger.info(f"Создана новая заявка: {service_request.id} для клиента: {client.email}") - # Генерация ссылки для регистрации в Telegram - try: + # Генерация ссылки и QR-кода для Telegram telegram_settings = get_object_or_404(TelegramSettings, pk=1) registration_link = f'https://t.me/{telegram_settings.bot_name}?start=request_{service_request.id}_token_{urlsafe_base64_encode(force_bytes(token))}' - except TelegramSettings.DoesNotExist: - logger.error("Не удалось получить настройки Telegram.") - return JsonResponse({'error': 'Не удалось получить настройки Telegram'}, status=500) - # Генерация QR-кода - try: 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") @@ -285,11 +204,14 @@ def generate_qr_code(request, service_id): os.makedirs(qr_code_dir) qr.save(qr_code_path) - except Exception as e: - logger.error(f"Ошибка при генерации QR-кода: {str(e)}") - return JsonResponse({'error': f'Ошибка при генерации QR-кода: {str(e)}'}, status=500) - # Возвращаем ответ, включающий все необходимые данные + except IntegrityError as e: + logger.error(f"Ошибка целостности данных при создании пользователя или клиента: {str(e)}") + return JsonResponse({'error': 'Ошибка при обработке данных. Пожалуйста, попробуйте позже.'}, status=500) + except Exception as e: + logger.error(f"Ошибка при обработке запроса: {str(e)}") + return JsonResponse({'error': f'Ошибка: {str(e)}'}, status=500) + return JsonResponse({ 'registration_link': registration_link, 'qr_code_url': f"/{external_qr_link}", @@ -298,104 +220,57 @@ def generate_qr_code(request, service_id): 'client_phone': client_phone, 'client_name': client_name }) - else: - logger.error("Неправильный метод запроса") - return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405) + return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405) - -def complete_registration(request, request_id): - # Завершение регистрации по идентификатору заявки - service_request = get_object_or_404(ServiceRequest, pk=request_id) - if request.method == 'POST': - client_email = request.POST.get('client_email', service_request.client.email) - client_phone = request.POST.get('client_phone', service_request.client.phone_number) - chat_id = request.POST.get('chat_id', service_request.chat_id) - - # Проверка корректности данных - if not all([client_email, client_phone, chat_id]): - return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены.'}, status=400) - - # Обновляем данные клиента - client = service_request.client - client.email = client_email - client.phone_number = client_phone - client.save() - - # Обновляем заявку - service_request.chat_id = chat_id - service_request.save() - - return JsonResponse({'status': 'success', 'message': 'Регистрация успешно завершена.'}) - - return render(request, 'web/complete_registration.html', {'service_request': service_request}) - - - return render(request, 'web/complete_registration.html', {'service_request': service_request}) def request_status(request, service_id): try: - # Получаем заявку на услугу по ID service_request = get_object_or_404(ServiceRequest, pk=service_id) - - # Получаем объект клиента через связанное поле client client = service_request.client + is_verified = service_request.is_verified - # Проверка, что клиент существует и его Telegram chat_id заполнен - is_verified = bool(client and client.chat_id) - - # Возвращаем данные клиента и статус верификации return JsonResponse({ 'is_verified': is_verified, 'client_name': client.first_name if client else "Неизвестно", 'client_chat_id': client.chat_id if client else None, }) except Exception as e: + logger.error(f"Ошибка при получении статуса заявки: {str(e)}") return JsonResponse({'error': str(e)}, status=500) -def complete_registration_basic(request): - # Базовая регистрация без идентификатора заявки +@csrf_exempt +def send_telegram_notification(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') - - 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 + data = json.loads(request.body) - 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}) + # Логируем полученные данные для отладки + logging.info(f"Полученные данные для подтверждения заявки: {data}") -def order_detail(request, pk): - order = get_object_or_404(Order, pk=pk) - return render(request, 'web/order_detail.html', {'order': order}) + service_request_id = data.get('service_request_id') + client_chat_id = data.get('client_chat_id') + client_name = data.get('client_name') -@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}) + if not service_request_id or not client_chat_id: + return JsonResponse({'error': 'Недостаточно данных для подтверждения'}, status=400) + + # Проверяем существование заявки + service_request = ServiceRequest.objects.filter(id=service_request_id).first() + if not service_request: + return JsonResponse({'error': 'Заявка не найдена'}, status=404) + + # Обновляем заявку с chat_id, если все верно + service_request.chat_id = client_chat_id + service_request.is_verified = True + service_request.save() + + return JsonResponse({'status': 'Уведомление успешно отправлено в Telegram'}) + + except json.JSONDecodeError as e: + logging.error(f"Ошибка при декодировании JSON: {e}") + return JsonResponse({'error': 'Неверный формат данных'}, status=400) + + logging.error(f"Неподдерживаемый метод запроса: {request.method}") + return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405) def generate_secure_token(service_request_id, secret_key): @@ -403,48 +278,24 @@ 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): +def complete_registration(request, request_id): + service_request = get_object_or_404(ServiceRequest, pk=request_id) if request.method == 'POST': - try: - data = json.loads(request.body) - service_request_id = data.get('service_request_id') - provided_token = data.get('token') + client_email = request.POST.get('client_email', service_request.client.email) + client_phone = request.POST.get('client_phone', service_request.client.phone_number) + chat_id = request.POST.get('chat_id', service_request.chat_id) - # Проверка корректности переданных данных - if not service_request_id or not provided_token: - return JsonResponse({'error': 'Недостаточно данных для подтверждения'}, status=400) + if not all([client_email, client_phone, chat_id]): + return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены.'}, status=400) - # Получение заявки - service_request = ServiceRequest.objects.filter(id=service_request_id).first() - if not service_request: - return JsonResponse({'error': 'Заявка не найдена'}, status=404) + client = service_request.client + client.email = client_email + client.phone_number = client_phone + client.save() - # Генерация токена и сравнение - secret_key = settings.SECRET_KEY # Используем секретный ключ из настроек - expected_token = generate_secure_token(service_request_id, secret_key) + service_request.chat_id = chat_id + service_request.save() - if not hmac.compare_digest(provided_token, expected_token): - return JsonResponse({'error': 'Неверный токен. Доступ запрещен.'}, status=403) + return JsonResponse({'status': 'success', 'message': 'Регистрация успешно завершена.'}) - # Отправка сообщения в Telegram - chat_id = service_request.chat_id - if not chat_id: - return JsonResponse({'error': 'Нет chat_id для отправки сообщения'}, status=400) - - # Составление и отправка сообщения - message = ( - f"Здравствуйте, {service_request.client.first_name}!\n" - f"Ваша заявка на услугу '{service_request.service.name}' успешно зарегистрирована." - ) - - bot.send_telegram_message(chat_id=chat_id, message=message) - - return JsonResponse({'status': 'Уведомление успешно отправлено в Telegram'}) - - except json.JSONDecodeError: - return JsonResponse({'error': 'Неверный формат данных'}, status=400) - except Exception as e: - return JsonResponse({'error': str(e)}, status=500) - - return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405) \ No newline at end of file + return render(request, 'web/complete_registration.html', {'service_request': service_request})