renew commit
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
__pycache__
|
__pycache__
|
||||||
.venv
|
.venv
|
||||||
.history
|
.history
|
||||||
|
static/qr_codes
|
||||||
1
smartsoltech/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
static/qr-qr_codes
|
||||||
@@ -126,6 +126,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import telebot
|
import telebot
|
||||||
|
from telebot import types
|
||||||
from decouple import config
|
from decouple import config
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from web.models import Client, ServiceRequest, Order
|
from web.models import Client, ServiceRequest, Order
|
||||||
@@ -152,7 +153,10 @@ class TelegramBot:
|
|||||||
if match:
|
if match:
|
||||||
self.handle_confirm_command(message, match)
|
self.handle_confirm_command(message, match)
|
||||||
elif message.text.strip() == '/start':
|
elif message.text.strip() == '/start':
|
||||||
self.bot.reply_to(message, "Ошибка: Некорректная команда. Пожалуйста, используйте ссылку, предоставленную на сайте для регистрации.")
|
kbd = types.InlineKeyboardMarkup()
|
||||||
|
url_btn = types.InlineKeyboardButton('Перейти на сайт', url=config("URL"))
|
||||||
|
kbd.add(url_btn)
|
||||||
|
self.bot.reply_to(message, "Здравствуйте! Данный бот предназначен для информирования клиентов SmartSolTech и регистрации на сайте. Пройдите на сайт для получения информации.", reply_markup = kbd)
|
||||||
else:
|
else:
|
||||||
self.bot.reply_to(message, "Здравствуйте! Пожалуйста, используйте команду /start с корректными параметрами для подтверждения регистрации.")
|
self.bot.reply_to(message, "Здравствуйте! Пожалуйста, используйте команду /start с корректными параметрами для подтверждения регистрации.")
|
||||||
|
|
||||||
@@ -161,11 +165,14 @@ class TelegramBot:
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
client = Client.objects.filter(chat_id=chat_id).first()
|
client = Client.objects.filter(chat_id=chat_id).first()
|
||||||
if client:
|
if client:
|
||||||
service_requests = ServiceRequest.objects.filter(client_email=client.email)
|
service_requests = ServiceRequest.objects.filter(chat_id=client.chat_id)
|
||||||
if service_requests.exists():
|
if service_requests.exists():
|
||||||
response = "Ваши заявки:\n"
|
response = "Ваши заявки:\n"
|
||||||
for req in service_requests:
|
for req in service_requests:
|
||||||
response += f"Номер заявки: {req.id}, Услуга: {req.service.name}, Дата создания: {req.created_at.strftime('%d-%m-%Y')}\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"
|
||||||
else:
|
else:
|
||||||
response = "У вас нет активных заявок."
|
response = "У вас нет активных заявок."
|
||||||
else:
|
else:
|
||||||
@@ -198,16 +205,14 @@ class TelegramBot:
|
|||||||
request_id = match.group(1)
|
request_id = match.group(1)
|
||||||
encoded_token = match.group(2)
|
encoded_token = match.group(2)
|
||||||
|
|
||||||
# Декодируем токен из base64
|
# Декодируем токен
|
||||||
try:
|
try:
|
||||||
token = base64.urlsafe_b64decode(encoded_token + '==').decode('utf-8')
|
token = base64.urlsafe_b64decode(encoded_token + '==').decode('utf-8')
|
||||||
logging.info(f"Декодированный токен: {token}")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Ошибка при декодировании токена: {e}")
|
|
||||||
self.bot.send_message(chat_id, "Ошибка: Некорректный токен. Пожалуйста, повторите попытку позже.")
|
self.bot.send_message(chat_id, "Ошибка: Некорректный токен. Пожалуйста, повторите попытку позже.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Получаем заявку по ID и токену
|
# Получаем заявку
|
||||||
service_request = ServiceRequest.objects.filter(id=request_id, token=token).first()
|
service_request = ServiceRequest.objects.filter(id=request_id, token=token).first()
|
||||||
if service_request:
|
if service_request:
|
||||||
# Обновляем chat_id клиента
|
# Обновляем chat_id клиента
|
||||||
@@ -215,12 +220,19 @@ class TelegramBot:
|
|||||||
service_request.client_name = message.from_user.first_name
|
service_request.client_name = message.from_user.first_name
|
||||||
service_request.save()
|
service_request.save()
|
||||||
|
|
||||||
response_message = (
|
# Отправляем данные обратно на сервер для создания заявки
|
||||||
f"Здравствуйте, {message.from_user.first_name}!\n"
|
data = {
|
||||||
f"Ваш Telegram аккаунт успешно подтвержден. Пожалуйста, вернитесь на сайт для заполнения остальных данных."
|
"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, "Ошибка при подтверждении. Пожалуйста, повторите попытку позже.")
|
||||||
else:
|
else:
|
||||||
response_message = "Ошибка: Неверная заявка или токен. Пожалуйста, проверьте ссылку."
|
self.bot.send_message(chat_id, "Ошибка: Неверная заявка или токен. Пожалуйста, проверьте ссылку.")
|
||||||
|
|
||||||
self.bot.send_message(chat_id, response_message)
|
self.bot.send_message(chat_id, response_message)
|
||||||
else:
|
else:
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
BIN
smartsoltech/static/qr_codes/request_330.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
smartsoltech/static/qr_codes/request_331.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
smartsoltech/static/qr_codes/request_332.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
smartsoltech/static/qr_codes/request_333.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
@@ -43,6 +43,6 @@ class CategoryAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(ServiceRequest)
|
@admin.register(ServiceRequest)
|
||||||
class ServiceRequestAdmin(admin.ModelAdmin):
|
class ServiceRequestAdmin(admin.ModelAdmin):
|
||||||
list_display = ('service','token', 'chat_id','client_name', 'client_email', 'client_phone', 'created_at')
|
list_display = ('service','token', 'client', 'created_at')
|
||||||
search_fields = ('service','token','client_name', 'client_email', 'client_phone')
|
search_fields = ('service','token', 'client')
|
||||||
list_filter = ('service','token','client_name', 'client_phone')
|
list_filter = ('service','token','client')
|
||||||
20
smartsoltech/web/migrations/0006_order_service_request.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2024-10-14 11:10
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('web', '0005_alter_blogpost_options_alter_category_options_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='service_request',
|
||||||
|
field=models.OneToOneField(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='related_order', to='web.servicerequest'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2024-10-14 11:46
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('web', '0006_order_service_request'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='servicerequest',
|
||||||
|
name='client_email',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='servicerequest',
|
||||||
|
name='client_name',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='servicerequest',
|
||||||
|
name='client_phone',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='servicerequest',
|
||||||
|
name='client',
|
||||||
|
field=models.ForeignKey(default=12, on_delete=django.db.models.deletion.CASCADE, related_name='related_service_requests', to='web.client'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2024-10-14 11:48
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('web', '0007_remove_servicerequest_client_email_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='servicerequest',
|
||||||
|
name='client',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='related_service_requests', to='web.client'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -70,9 +70,25 @@ class BlogPost(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
class ServiceRequest(models.Model):
|
||||||
|
service = models.ForeignKey(Service, on_delete=models.CASCADE)
|
||||||
|
client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='related_service_requests', null=True, blank=True)
|
||||||
|
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
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Заявка на услугу'
|
||||||
|
verbose_name_plural = 'Заявки на услуги'
|
||||||
|
ordering = ['-created_at']
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Request for {self.service.name} by {self.client.first_name}"
|
||||||
|
|
||||||
class Order(models.Model):
|
class Order(models.Model):
|
||||||
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='related_orders')
|
service_request = models.OneToOneField(ServiceRequest, on_delete=models.CASCADE, related_name='related_order')
|
||||||
client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='related_orders')
|
client = models.ForeignKey(Client, on_delete=models.CASCADE, related_name='related_orders')
|
||||||
|
service = models.ForeignKey(Service, on_delete=models.CASCADE, related_name='related_orders')
|
||||||
message = models.TextField(blank=True, null=True)
|
message = models.TextField(blank=True, null=True)
|
||||||
order_date = models.DateTimeField(auto_now_add=True)
|
order_date = models.DateTimeField(auto_now_add=True)
|
||||||
status = models.CharField(
|
status = models.CharField(
|
||||||
@@ -136,19 +152,3 @@ class Review(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Review by {self.client.first_name} {self.client.last_name} for {self.service.name}"
|
return f"Review by {self.client.first_name} {self.client.last_name} for {self.service.name}"
|
||||||
|
|
||||||
class ServiceRequest(models.Model):
|
|
||||||
service = models.ForeignKey(Service, on_delete=models.CASCADE)
|
|
||||||
client_name = models.CharField(max_length=100)
|
|
||||||
client_email = models.EmailField()
|
|
||||||
client_phone = models.CharField(max_length=20)
|
|
||||||
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
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = 'Заявка на услугу'
|
|
||||||
verbose_name_plural = 'Заявки на услуги'
|
|
||||||
ordering = ['-created_at']
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"Request for {self.service.name} by {self.client_name}"
|
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#qrCodeImg {
|
#qrCodeImg {
|
||||||
display: block;
|
display: none;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
@@ -58,17 +58,7 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<span class="close">×</span>
|
<span class="close">×</span>
|
||||||
<h4>Заполните заявку на услугу</h4>
|
<h4>Заполните заявку на услугу</h4>
|
||||||
<p>QR-код для завершения регистрации:</p>
|
|
||||||
<img id="qrCodeImg" src="" alt="QR Code">
|
|
||||||
<form id="serviceRequestForm">
|
<form id="serviceRequestForm">
|
||||||
<div class="form-group">
|
|
||||||
<label for="clientName">Ваше имя:</label>
|
|
||||||
<input type="text" class="form-control" id="clientName" name="client_name" placeholder="Введите ваше имя" required minlength="2" maxlength="50" readonly>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="clientChatId">Ваш chat ID:</label>
|
|
||||||
<input type="text" class="form-control" id="clientChatId" name="client_chat_id" placeholder="Ваш chat ID" readonly>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="clientEmail">Ваш email:</label>
|
<label for="clientEmail">Ваш email:</label>
|
||||||
<input type="email" class="form-control" id="clientEmail" name="client_email" placeholder="Введите ваш email" required>
|
<input type="email" class="form-control" id="clientEmail" name="client_email" placeholder="Введите ваш email" required>
|
||||||
@@ -81,71 +71,101 @@
|
|||||||
<label for="description">Описание заявки:</label>
|
<label for="description">Описание заявки:</label>
|
||||||
<textarea class="form-control" id="description" name="description" placeholder="Опишите вашу заявку" required></textarea>
|
<textarea class="form-control" id="description" name="description" placeholder="Опишите вашу заявку" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-success" id="submitButton" disabled>Отправить заявку</button>
|
<button type="button" class="btn btn-primary" id="generateQrButton">Продолжить</button>
|
||||||
</form>
|
</form>
|
||||||
|
<div id="qrCodeContainer">
|
||||||
|
<p>QR-код для завершения регистрации:</p>
|
||||||
|
<img id="qrCodeImg" src="" alt="QR Code">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="confirmationModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close">×</span>
|
||||||
|
<h4>Заявка успешно создана!</h4>
|
||||||
|
<p>Ваши данные были отправлены и заявка зарегистрирована. Пожалуйста, проверьте ваш Telegram для получения подтверждения.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Обработчик открытия модального окна
|
// Обработчик открытия модального окна
|
||||||
document.getElementById('openModalBtn').addEventListener('click', function () {
|
document.getElementById('openModalBtn').addEventListener('click', function () {
|
||||||
const serviceId = this.getAttribute('data-service-id');
|
|
||||||
// Открываем модальное окно
|
// Открываем модальное окно
|
||||||
document.getElementById('serviceModal').style.display = 'block';
|
document.getElementById('serviceModal').style.display = 'block';
|
||||||
|
|
||||||
// Выполняем запрос на генерацию QR-кода
|
|
||||||
fetch(`/service/generate_qr_code/${serviceId}/`)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
// Обновляем src изображения QR-кода
|
|
||||||
document.getElementById('qrCodeImg').src = data.qr_code_url;
|
|
||||||
|
|
||||||
// Запуск проверки статуса каждые 5 секунд
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
checkVerificationStatus(data.service_request_id, interval);
|
|
||||||
}, 5000);
|
|
||||||
})
|
|
||||||
.catch(error => console.error('Ошибка при генерации QR-кода:', error));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Обработчик закрытия модального окна
|
// Обработчик закрытия модального окна
|
||||||
document.querySelector('.close').addEventListener('click', function () {
|
document.querySelectorAll('.close').forEach(closeBtn => {
|
||||||
document.getElementById('serviceModal').style.display = 'none';
|
closeBtn.addEventListener('click', function () {
|
||||||
|
document.getElementById('serviceModal').style.display = 'none';
|
||||||
|
document.getElementById('confirmationModal').style.display = 'none';
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Обработчик отправки формы
|
// Обработчик кнопки "Продолжить" для генерации QR-кода
|
||||||
document.getElementById('serviceRequestForm').addEventListener('submit', function (event) {
|
document.getElementById('generateQrButton').addEventListener('click', function () {
|
||||||
event.preventDefault();
|
const clientEmail = document.getElementById('clientEmail').value;
|
||||||
const formData = new FormData(this);
|
const clientPhone = document.getElementById('clientPhone').value;
|
||||||
const serviceId = document.getElementById('openModalBtn').getAttribute('data-service-id');
|
const description = document.getElementById('description').value;
|
||||||
// Отправка данных формы на сервер
|
|
||||||
fetch('/service/request/' + serviceId + '/', {
|
if (clientEmail && clientPhone && description) {
|
||||||
method: 'POST',
|
// Выполняем запрос на генерацию QR-кода
|
||||||
body: formData
|
const openModalBtn = document.getElementById('openModalBtn');
|
||||||
}).then(response => {
|
if (!openModalBtn) {
|
||||||
if (response.ok) {
|
console.error('Не удалось найти элемент openModalBtn');
|
||||||
alert('Заявка успешно отправлена!');
|
return;
|
||||||
document.getElementById('serviceModal').style.display = 'none';
|
|
||||||
// Отправка сообщения в Telegram
|
|
||||||
sendTelegramNotification(formData);
|
|
||||||
} else {
|
|
||||||
alert('Ошибка при отправке заявки. Пожалуйста, попробуйте снова.');
|
|
||||||
}
|
}
|
||||||
}).catch(error => console.error('Ошибка при отправке данных формы:', error));
|
|
||||||
|
const serviceId = openModalBtn.getAttribute('data-service-id');
|
||||||
|
if (!serviceId) {
|
||||||
|
console.error('Не удалось найти идентификатор услуги');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`/service/generate_qr_code/${serviceId}/`)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Ошибка при генерации QR-кода');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
// Проверка наличия ссылки на QR-код в ответе
|
||||||
|
if (!data.qr_code_url) {
|
||||||
|
throw new Error('Ответ не содержит QR-код');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем src изображения QR-кода и показываем его
|
||||||
|
const qrCodeImg = document.getElementById('qrCodeImg');
|
||||||
|
qrCodeImg.src = data.qr_code_url;
|
||||||
|
qrCodeImg.style.display = 'block';
|
||||||
|
|
||||||
|
// Запуск проверки статуса каждые 5 секунд
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
checkVerificationStatus(data.service_request_id, interval, clientEmail, clientPhone, description);
|
||||||
|
}, 5000);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Ошибка при генерации QR-кода:', error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('Поля email, телефон и описание обязательны');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Проверка статуса заявки на наличие подтверждения Telegram
|
// Проверка статуса заявки на наличие подтверждения Telegram
|
||||||
const checkVerificationStatus = (serviceRequestId, interval) => {
|
const checkVerificationStatus = (serviceRequestId, interval, clientEmail, clientPhone, description) => {
|
||||||
fetch(`/service/request_status/${serviceRequestId}/`)
|
fetch(`/service/request_status/${serviceRequestId}/`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.is_verified) {
|
if (data.is_verified) {
|
||||||
// Заполнение полей формы данными пользователя
|
// Закрываем форму и открываем окно подтверждения
|
||||||
document.getElementById('clientName').value = data.client_name;
|
document.getElementById('serviceModal').style.display = 'none';
|
||||||
document.getElementById('clientChatId').value = data.client_chat_id;
|
document.getElementById('confirmationModal').style.display = 'block';
|
||||||
|
|
||||||
// Активируем кнопку отправки, если все поля заполнены
|
// Создание заявки с использованием данных формы и Telegram
|
||||||
updateButtonState();
|
createServiceRequest(serviceRequestId, data.client_name, data.client_chat_id, clientEmail, clientPhone, description);
|
||||||
|
|
||||||
// Останавливаем интервал проверки статуса
|
// Останавливаем интервал проверки статуса
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
@@ -154,43 +174,36 @@
|
|||||||
.catch(error => console.error('Ошибка при проверке статуса заявки:', error));
|
.catch(error => console.error('Ошибка при проверке статуса заявки:', error));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Код для активации кнопки "Отправить" при заполнении всех полей
|
// Создание заявки с использованием данных из формы и Telegram
|
||||||
const clientEmail = document.getElementById('clientEmail');
|
const createServiceRequest = (serviceRequestId, clientName, chatId, clientEmail, clientPhone, description) => {
|
||||||
const clientPhone = document.getElementById('clientPhone');
|
fetch('/service/create_request/', {
|
||||||
const clientName = document.getElementById('clientName');
|
method: 'POST',
|
||||||
const description = document.getElementById('description');
|
headers: {
|
||||||
const clientChatId = document.getElementById('clientChatId');
|
'Content-Type': 'application/json'
|
||||||
const submitButton = document.getElementById('submitButton');
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
const updateButtonState = () => {
|
service_request_id: serviceRequestId,
|
||||||
if (clientEmail.value && clientPhone.value && clientName.value && description.value && clientChatId.value) {
|
client_name: clientName,
|
||||||
submitButton.disabled = false;
|
client_chat_id: chatId,
|
||||||
} else {
|
client_email: clientEmail,
|
||||||
submitButton.disabled = true;
|
client_phone: clientPhone,
|
||||||
}
|
description: description
|
||||||
|
})
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
console.log('Заявка успешно создана');
|
||||||
|
sendTelegramNotification({ client_name: clientName, client_chat_id: chatId, description: description });
|
||||||
|
} else {
|
||||||
|
console.error('Ошибка при создании заявки');
|
||||||
|
}
|
||||||
|
}).catch(error => console.error('Ошибка при создании заявки:', error));
|
||||||
};
|
};
|
||||||
|
|
||||||
// Привязка событий к полям для обновления состояния кнопки отправки
|
|
||||||
clientEmail.addEventListener('input', updateButtonState);
|
|
||||||
clientPhone.addEventListener('input', updateButtonState);
|
|
||||||
description.addEventListener('input', updateButtonState);
|
|
||||||
|
|
||||||
// Удаление placeholder при установке фокуса на поле
|
|
||||||
document.querySelectorAll('input, textarea').forEach(field => {
|
|
||||||
field.addEventListener('focus', function () {
|
|
||||||
this.dataset.placeholder = this.placeholder;
|
|
||||||
this.placeholder = '';
|
|
||||||
});
|
|
||||||
field.addEventListener('blur', function () {
|
|
||||||
this.placeholder = this.dataset.placeholder;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Функция для отправки уведомления в Telegram
|
// Функция для отправки уведомления в Telegram
|
||||||
const sendTelegramNotification = (formData) => {
|
const sendTelegramNotification = (data) => {
|
||||||
const clientName = formData.get('client_name');
|
const clientName = data.client_name;
|
||||||
const serviceDescription = formData.get('description');
|
const serviceDescription = data.description;
|
||||||
const chatId = formData.get('client_chat_id');
|
const chatId = data.client_chat_id;
|
||||||
const message = `Здравствуйте, ${clientName}! Ваша заявка успешно зарегистрирована. Детали: ${serviceDescription}`;
|
const message = `Здравствуйте, ${clientName}! Ваша заявка успешно зарегистрирована. Детали: ${serviceDescription}`;
|
||||||
|
|
||||||
fetch('/service/send_telegram_notification/', {
|
fetch('/service/send_telegram_notification/', {
|
||||||
@@ -208,6 +221,7 @@
|
|||||||
}).catch(error => console.error('Ошибка при отправке уведомления в Telegram:', error));
|
}).catch(error => console.error('Ошибка при отправке уведомления в Telegram:', error));
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,161 +1,214 @@
|
|||||||
<!-- web/templates/web/modal_order_form.html -->
|
<!DOCTYPE html>
|
||||||
<div id="orderModal" class="modal fade" tabindex="-1">
|
<html lang="ru">
|
||||||
<div class="modal-dialog">
|
<head>
|
||||||
<div class="modal-content">
|
<meta charset="UTF-8">
|
||||||
<div class="modal-header">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<h5 class="modal-title">Оформление заявки на услугу</h5>
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
||||||
|
<title>Модальное окно для заявки на услугу</title>
|
||||||
|
<style>
|
||||||
|
/* Стили для модального окна */
|
||||||
|
.modal {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 15% auto;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qrCodeImg {
|
||||||
|
display: block;
|
||||||
|
margin: 20px auto;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Модальное окно -->
|
||||||
|
<div id="serviceModal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<span class="close">×</span>
|
||||||
|
<h4>Заполните заявку на услугу</h4>
|
||||||
|
<p>QR-код для завершения регистрации:</p>
|
||||||
|
<img id="qrCodeImg" src="" alt="QR Code">
|
||||||
|
<form id="serviceRequestForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="clientName">Ваше имя:</label>
|
||||||
|
<input type="text" class="form-control" id="clientName" name="client_name" placeholder="Введите ваше имя" required minlength="2" maxlength="50" readonly>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="form-group">
|
||||||
<form id="orderForm" method="post" action="{% url 'create_service_request' service_id=service.pk %}">
|
<label for="clientChatId">Ваш chat ID:</label>
|
||||||
{% csrf_token %}
|
<input type="text" class="form-control" id="clientChatId" name="client_chat_id" placeholder="Ваш chat ID" readonly>
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label">Имя</label>
|
|
||||||
<input id="client_name" class="form-control" type="text" name="client_name" required minlength="2" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label">Телефон</label>
|
|
||||||
<input id="client_phone" class="form-control" type="tel" name="client_phone" required pattern="^\+?[0-9\s\-]{7,15}$" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label">Адрес электронной почты</label>
|
|
||||||
<input id="client_email" class="form-control" type="email" name="client_email" required />
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-3 text-center">
|
|
||||||
<label class="form-label">Сканируйте QR код для регистрации в Telegram боте</label>
|
|
||||||
<div id="qrCodeContainer">
|
|
||||||
<img id="qrCodeImage" src="{{ qr_code_url }}" alt="QR код для Telegram бота" class="img-fluid" style="max-width: 150px;" />
|
|
||||||
</div>
|
|
||||||
<div class="form-group mt-3">
|
|
||||||
<a id="registrationLink" href="#" target="_blank">Перейдите по этой ссылке для регистрации в Telegram боте</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" id="submitButton" disabled>Отправить заявку</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{% comment %} <div id="diagnostic_info" class="mt-3">
|
|
||||||
<form id="registrationForm">
|
|
||||||
<h3>Диагностическая информация</h3>
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label for="registrationLinkField" class="form-label">Ссылка для регистрации в Telegram боте:</label>
|
|
||||||
<input type="text" id="registrationLinkField" class="form-control" readonly />
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label for="requestIdField" class="form-label">Номер заявки:</label>
|
|
||||||
<input type="text" id="requestIdField" class="form-control" readonly />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div> {% endcomment %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group">
|
||||||
|
<label for="clientEmail">Ваш email:</label>
|
||||||
|
<input type="email" class="form-control" id="clientEmail" name="client_email" placeholder="Введите ваш email" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="clientPhone">Ваш телефон:</label>
|
||||||
|
<input type="text" class="form-control" id="clientPhone" name="client_phone" placeholder="Введите ваш телефон" required pattern="^\+?[0-9\s\-]{7,15}$">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="description">Описание заявки:</label>
|
||||||
|
<textarea class="form-control" id="description" name="description" placeholder="Опишите вашу заявку" required></textarea>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-success" id="submitButton" disabled>Отправить заявку</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
// Обработчик открытия модального окна
|
||||||
const form = document.getElementById('registrationForm');
|
document.getElementById('openModalBtn').addEventListener('click', function () {
|
||||||
const submitButton = document.getElementById('submitButton');
|
const serviceId = this.getAttribute('data-service-id');
|
||||||
const qrCodeImage = document.getElementById('qrCodeImage');
|
// Открываем модальное окно
|
||||||
const registrationLink = document.getElementById('registrationLink');
|
document.getElementById('serviceModal').style.display = 'block';
|
||||||
let serviceId = "{{ service.pk }}"; // Получаем значение serviceId из шаблона
|
|
||||||
|
|
||||||
// Генерация QR-кода при открытии формы
|
// Выполняем запрос на генерацию QR-кода
|
||||||
fetch(`/service/generate_qr_code/${serviceId}/`)
|
fetch(`/service/generate_qr_code/${serviceId}/`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
qrCodeImage.src = data.qr_code_url;
|
// Обновляем src изображения QR-кода
|
||||||
registrationLink.href = data.registration_link;
|
document.getElementById('qrCodeImg').src = data.qr_code_url;
|
||||||
|
|
||||||
// Извлекаем номер заявки из ссылки на регистрацию
|
|
||||||
const requestMatch = data.registration_link.match(/request_(\d+)_token/);
|
|
||||||
if (requestMatch) {
|
|
||||||
serviceId = requestMatch[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Отображение диагностической информации на форме
|
|
||||||
//document.getElementById('registrationLinkField').value = data.registration_link;
|
|
||||||
//document.getElementById('requestIdField').value = serviceId;
|
|
||||||
|
|
||||||
// Запуск проверки статуса каждые 5 секунд
|
// Запуск проверки статуса каждые 5 секунд
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
checkVerificationStatus(serviceId, interval);
|
checkVerificationStatus(data.service_request_id, interval);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
})
|
})
|
||||||
.catch(error => console.error('Ошибка при генерации QR-кода:', error));
|
.catch(error => console.error('Ошибка при генерации QR-кода:', error));
|
||||||
|
|
||||||
const checkVerificationStatus = (serviceId, interval) => {
|
|
||||||
fetch(`/service/request_status/${serviceId}/`)
|
|
||||||
.then(response => {
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error('Network response was not ok');
|
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
if (data.is_verified) {
|
|
||||||
// Заполнение полей формы данными пользователя
|
|
||||||
document.getElementById('client_name').value = data.client_name;
|
|
||||||
document.getElementById('client_email').value = data.client_email;
|
|
||||||
document.getElementById('client_phone').value = data.client_phone;
|
|
||||||
|
|
||||||
// Активируем кнопку отправки, если поля заполнены
|
|
||||||
updateButtonState();
|
|
||||||
|
|
||||||
// Останавливаем интервал проверки статуса
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => console.error('Ошибка при проверке статуса:', error));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Обработчик кнопки отправки формы
|
|
||||||
submitButton.addEventListener('click', function () {
|
|
||||||
if (submitButton.disabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Проверка наличия данных в таблице ServiceRequest перед отправкой формы
|
|
||||||
fetch(`/service/check_service_request_data/?request_id=${serviceId}`)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.exists) {
|
|
||||||
// Обратная связь пользователю
|
|
||||||
alert('Заявка уже существует. Данные будут обновлены.');
|
|
||||||
|
|
||||||
// Заполнение формы данными из заявки
|
|
||||||
document.getElementById('client_name').value = data.client_name;
|
|
||||||
document.getElementById('client_email').value = data.client_email;
|
|
||||||
document.getElementById('client_phone').value = data.client_phone;
|
|
||||||
|
|
||||||
// Отправка формы
|
|
||||||
form.submit();
|
|
||||||
} else {
|
|
||||||
// Если данных нет, отправляем форму как новую заявку
|
|
||||||
form.submit();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Ошибка при проверке данных заявки:', error);
|
|
||||||
alert('Произошла ошибка при проверке данных. Пожалуйста, попробуйте еще раз.');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Код для активации кнопки "Отправить" при заполнении полей телефона и email
|
|
||||||
const clientEmail = document.getElementById('client_email');
|
|
||||||
const clientPhone = document.getElementById('client_phone');
|
|
||||||
|
|
||||||
const updateButtonState = () => {
|
|
||||||
if (clientEmail.value && clientPhone.value) {
|
|
||||||
submitButton.disabled = false;
|
|
||||||
} else {
|
|
||||||
submitButton.disabled = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Привязка событий к полям email и телефона
|
|
||||||
clientEmail.addEventListener('input', updateButtonState);
|
|
||||||
clientPhone.addEventListener('input', updateButtonState);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Обработчик закрытия модального окна
|
||||||
|
document.querySelector('.close').addEventListener('click', function () {
|
||||||
|
document.getElementById('serviceModal').style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Обработчик отправки формы
|
||||||
|
document.getElementById('serviceRequestForm').addEventListener('submit', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const formData = new FormData(this);
|
||||||
|
const serviceId = document.getElementById('openModalBtn').getAttribute('data-service-id');
|
||||||
|
// Отправка данных формы на сервер
|
||||||
|
fetch('/service/request/' + serviceId + '/', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
alert('Заявка успешно отправлена!');
|
||||||
|
document.getElementById('serviceModal').style.display = 'none';
|
||||||
|
// Отправка сообщения в Telegram
|
||||||
|
sendTelegramNotification(formData);
|
||||||
|
} else {
|
||||||
|
alert('Ошибка при отправке заявки. Пожалуйста, попробуйте снова.');
|
||||||
|
}
|
||||||
|
}).catch(error => console.error('Ошибка при отправке данных формы:', error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Проверка статуса заявки на наличие подтверждения Telegram
|
||||||
|
const checkVerificationStatus = (serviceRequestId, interval) => {
|
||||||
|
fetch(`/service/request_status/${serviceRequestId}/`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.is_verified) {
|
||||||
|
// Заполнение полей формы данными пользователя
|
||||||
|
document.getElementById('clientName').value = data.client_name;
|
||||||
|
document.getElementById('clientChatId').value = data.client_chat_id;
|
||||||
|
|
||||||
|
// Активируем кнопку отправки, если все поля заполнены
|
||||||
|
updateButtonState();
|
||||||
|
|
||||||
|
// Останавливаем интервал проверки статуса
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Ошибка при проверке статуса заявки:', error));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Код для активации кнопки "Отправить" при заполнении всех полей
|
||||||
|
const clientEmail = document.getElementById('clientEmail');
|
||||||
|
const clientPhone = document.getElementById('clientPhone');
|
||||||
|
const clientName = document.getElementById('clientName');
|
||||||
|
const description = document.getElementById('description');
|
||||||
|
const clientChatId = document.getElementById('clientChatId');
|
||||||
|
const submitButton = document.getElementById('submitButton');
|
||||||
|
|
||||||
|
const updateButtonState = () => {
|
||||||
|
if (clientEmail.value && clientPhone.value && clientName.value && description.value && clientChatId.value) {
|
||||||
|
submitButton.disabled = false;
|
||||||
|
} else {
|
||||||
|
submitButton.disabled = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Привязка событий к полям для обновления состояния кнопки отправки
|
||||||
|
clientEmail.addEventListener('input', updateButtonState);
|
||||||
|
clientPhone.addEventListener('input', updateButtonState);
|
||||||
|
description.addEventListener('input', updateButtonState);
|
||||||
|
|
||||||
|
// Удаление placeholder при установке фокуса на поле
|
||||||
|
document.querySelectorAll('input, textarea').forEach(field => {
|
||||||
|
field.addEventListener('focus', function () {
|
||||||
|
this.dataset.placeholder = this.placeholder;
|
||||||
|
this.placeholder = '';
|
||||||
|
});
|
||||||
|
field.addEventListener('blur', function () {
|
||||||
|
this.placeholder = this.dataset.placeholder;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Функция для отправки уведомления в Telegram
|
||||||
|
const sendTelegramNotification = (formData) => {
|
||||||
|
const clientName = formData.get('client_name');
|
||||||
|
const serviceDescription = formData.get('description');
|
||||||
|
const chatId = formData.get('client_chat_id');
|
||||||
|
const message = `Здравствуйте, ${clientName}! Ваша заявка успешно зарегистрирована. Детали: ${serviceDescription}`;
|
||||||
|
|
||||||
|
fetch('/service/send_telegram_notification/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ chat_id: chatId, message: message })
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
console.log('Уведомление успешно отправлено в Telegram');
|
||||||
|
} else {
|
||||||
|
console.error('Ошибка при отправке уведомления в Telegram');
|
||||||
|
}
|
||||||
|
}).catch(error => console.error('Ошибка при отправке уведомления в Telegram:', error));
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -14,8 +14,7 @@
|
|||||||
<div style="max-width: 350px;">
|
<div style="max-width: 350px;">
|
||||||
<h2 class="text-uppercase fw-bold">{{ service.name }}<br /></h2>
|
<h2 class="text-uppercase fw-bold">{{ service.name }}<br /></h2>
|
||||||
<p class="my-3">{{ service.description }}</p>
|
<p class="my-3">{{ service.description }}</p>
|
||||||
<button id="orderButton" data-service-id="{{ service.pk }}" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#orderModal">Заказать услугу</button>
|
<!-- Кнопка открытия модального окна -->
|
||||||
<!-- Кнопка открытия модального окна -->
|
|
||||||
<button id="openModalBtn" class="btn btn-primary" data-service-id="{{ service.id }}">Открыть заявку на услугу</button>
|
<button id="openModalBtn" class="btn btn-primary" data-service-id="{{ service.id }}">Открыть заявку на услугу</button>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,104 +64,185 @@ def services_view(request):
|
|||||||
def about_view(request):
|
def about_view(request):
|
||||||
return render(request, 'web/about.html')
|
return render(request, 'web/about.html')
|
||||||
|
|
||||||
|
# def create_service_request(request, service_id):
|
||||||
|
# service = get_object_or_404(Service, pk=service_id)
|
||||||
|
# if request.method == 'POST':
|
||||||
|
# client_name = request.POST.get('client_name')
|
||||||
|
# client_email = request.POST.get('client_email')
|
||||||
|
# client_phone = request.POST.get('client_phone')
|
||||||
|
# description = request.POST.get('description')
|
||||||
|
# chat_id = request.POST.get('chat_id')
|
||||||
|
# token = uuid.uuid4().hex
|
||||||
|
|
||||||
|
# # Создаем заявку
|
||||||
|
# service_request = ServiceRequest.objects.create(
|
||||||
|
# service=service,
|
||||||
|
# client_name=client_name,
|
||||||
|
# client_email=client_email,
|
||||||
|
# client_phone=client_phone,
|
||||||
|
# chat_id=chat_id,
|
||||||
|
# token=token
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Генерация уникальных данных для пользователя
|
||||||
|
# username = f"{client_email.split('@')[0]}_{get_random_string(5)}"
|
||||||
|
# password = get_random_string(8)
|
||||||
|
|
||||||
|
# # Создание пользователя
|
||||||
|
# user = User.objects.create_user(username=username, password=password)
|
||||||
|
# user.first_name = client_name.split()[0] if client_name else ""
|
||||||
|
# user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else ""
|
||||||
|
# user.email = client_email
|
||||||
|
# user.save()
|
||||||
|
|
||||||
|
# # Создание клиента и привязка к пользователю
|
||||||
|
# client, created = 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,
|
||||||
|
# 'chat_id': chat_id,
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Создание заказа на основе заявки
|
||||||
|
# order = Order.objects.create(
|
||||||
|
# service_request=service_request,
|
||||||
|
# client=client,
|
||||||
|
# service=service,
|
||||||
|
# message=description,
|
||||||
|
# status="pending"
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Отправка сообщения в Telegram
|
||||||
|
# if chat_id:
|
||||||
|
# bot.send_telegram_message(client.id, service_request.id, "Ваши данные для входа на сайт.", order.id)
|
||||||
|
|
||||||
|
# return redirect(reverse('order_detail', args=[order.pk]))
|
||||||
|
|
||||||
|
# return render(request, 'web/create_service_request.html', {'service': service})
|
||||||
|
|
||||||
def create_service_request(request, service_id):
|
def create_service_request(request, service_id):
|
||||||
service = get_object_or_404(Service, pk=service_id)
|
service = get_object_or_404(Service, pk=service_id)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
client_name = request.POST.get('client_name')
|
# Извлечение данных формы
|
||||||
client_email = request.POST.get('client_email')
|
client_email = request.POST.get('client_email')
|
||||||
client_phone = request.POST.get('client_phone')
|
client_phone = request.POST.get('client_phone')
|
||||||
description = request.POST.get('description') # New description field
|
description = request.POST.get('description')
|
||||||
chat_id = request.POST.get('chat_id')
|
chat_id = request.POST.get('client_chat_id')
|
||||||
token = uuid.uuid4().hex
|
client_name = request.POST.get('client_name')
|
||||||
|
|
||||||
# Check for existing service request
|
# Проверка на наличие существующей заявки
|
||||||
service_request = ServiceRequest.objects.filter(client_email=client_email, client_phone=client_phone).first()
|
service_request = get_object_or_404(ServiceRequest, chat_id=chat_id)
|
||||||
|
|
||||||
if not service_request:
|
# Обновление данных заявки
|
||||||
# Create a new service request
|
service_request.client_email = client_email
|
||||||
service_request = ServiceRequest.objects.create(
|
service_request.client_phone = client_phone
|
||||||
service=service,
|
service_request.message = description
|
||||||
client_name=client_name,
|
service_request.save()
|
||||||
client_email=client_email,
|
|
||||||
client_phone=client_phone,
|
|
||||||
chat_id=chat_id,
|
|
||||||
token=token
|
|
||||||
)
|
|
||||||
|
|
||||||
# Generate user credentials
|
# Создание клиента и пользователя, если необходимо
|
||||||
username = f"{client_email.split('@')[0]}_{get_random_string(5)}"
|
user, _ = User.objects.get_or_create(
|
||||||
password = get_random_string(8)
|
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()
|
||||||
|
|
||||||
# Create a new user
|
client, _ = Client.objects.get_or_create(
|
||||||
user = User.objects.create_user(username=username, password=password)
|
email=client_email,
|
||||||
user.first_name = client_name.split()[0] if client_name else ""
|
defaults={
|
||||||
user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else ""
|
'user': user,
|
||||||
user.email = client_email
|
'first_name': user.first_name,
|
||||||
user.save()
|
'last_name': user.last_name,
|
||||||
|
'phone_number': client_phone,
|
||||||
|
'chat_id': chat_id,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Create or get client
|
# Создание заказа, связанного с заявкой
|
||||||
client, created = Client.objects.get_or_create(
|
order = Order.objects.create(
|
||||||
email=client_email,
|
service_request=service_request,
|
||||||
defaults={
|
client=client,
|
||||||
'first_name': user.first_name,
|
service=service_request.service,
|
||||||
'last_name': user.last_name,
|
message=description,
|
||||||
'phone_number': client_phone,
|
status="pending"
|
||||||
}
|
)
|
||||||
)
|
|
||||||
|
|
||||||
# Create an order linked to the service request and client
|
# Отправка уведомления в Telegram
|
||||||
order = Order.objects.create(
|
bot.send_telegram_message(
|
||||||
service=service,
|
client.id,
|
||||||
client=client,
|
service_request.id,
|
||||||
message=description,
|
f"Ваш заказ на услугу '{service_request.service.name}' был успешно создан.",
|
||||||
status="pending"
|
order.id
|
||||||
)
|
)
|
||||||
|
|
||||||
# Send credentials via Telegram
|
|
||||||
if chat_id:
|
|
||||||
bot.send_telegram_message(client.id, service_request.id, "Ваши данные для входа на сайт.", order.id)
|
|
||||||
|
|
||||||
else:
|
|
||||||
# If service request exists, update the chat_id
|
|
||||||
service_request.chat_id = chat_id
|
|
||||||
service_request.save()
|
|
||||||
|
|
||||||
return redirect(reverse('order_detail', args=[order.pk]))
|
return redirect(reverse('order_detail', args=[order.pk]))
|
||||||
|
|
||||||
|
return render(request, 'web/create_service_request.html', {'service': service})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate_qr_code(request, service_id):
|
def generate_qr_code(request, service_id):
|
||||||
service = get_object_or_404(Service, pk=service_id)
|
if request.method == 'POST':
|
||||||
telegram_settings = get_object_or_404(TelegramSettings, pk=1)
|
client_email = request.POST.get('client_email')
|
||||||
token = uuid.uuid4().hex
|
client_phone = request.POST.get('client_phone')
|
||||||
|
client_name = request.POST.get('client_name')
|
||||||
|
|
||||||
# Создание новой заявки на услугу
|
# Создание или получение клиента
|
||||||
service_request = ServiceRequest.objects.create(
|
user, _ = User.objects.get_or_create(
|
||||||
service=service,
|
username=f"{client_email.split('@')[0]}_{get_random_string(5)}",
|
||||||
client_name='',
|
defaults={"email": client_email}
|
||||||
client_email='',
|
)
|
||||||
client_phone='',
|
user.first_name = client_name.split()[0] if client_name else ""
|
||||||
token=token
|
user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else ""
|
||||||
)
|
user.save()
|
||||||
|
|
||||||
# Генерация ссылки для регистрации в Telegram
|
client, _ = Client.objects.get_or_create(
|
||||||
registration_link = (f'https://t.me/{telegram_settings.bot_name}?start=request_{service_request.id}_token_{urlsafe_base64_encode(force_bytes(token))}'
|
email=client_email,
|
||||||
)
|
defaults={
|
||||||
|
'user': user,
|
||||||
|
'first_name': user.first_name,
|
||||||
|
'last_name': user.last_name,
|
||||||
|
'phone_number': client_phone
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Генерация QR-кода
|
# Создание новой заявки на услугу
|
||||||
qr = qrcode.make(registration_link)
|
service = get_object_or_404(Service, pk=service_id)
|
||||||
qr_code_dir = os.path.join(settings.STATICFILES_DIRS[0], 'qr_codes')
|
token = uuid.uuid4().hex
|
||||||
qr_code_path = os.path.join(qr_code_dir, f"request_{service_request.id}.png")
|
|
||||||
external_qr_link = f'static/qr_codes/request_{service_request.id}.png'
|
|
||||||
|
|
||||||
if not os.path.exists(qr_code_dir):
|
service_request = ServiceRequest.objects.create(
|
||||||
os.makedirs(qr_code_dir)
|
service=service,
|
||||||
|
client=client,
|
||||||
|
token=token
|
||||||
|
)
|
||||||
|
|
||||||
qr.save(qr_code_path)
|
# Генерация ссылки для регистрации в 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))}'
|
||||||
|
|
||||||
return JsonResponse({
|
# Генерация QR-кода
|
||||||
'registration_link': registration_link,
|
qr = qrcode.make(registration_link)
|
||||||
'qr_code_url': f"/{external_qr_link}",
|
qr_code_dir = os.path.join(settings.STATICFILES_DIRS[0], 'qr_codes')
|
||||||
'service_request_id': service_request.id
|
qr_code_path = os.path.join(qr_code_dir, f"request_{service_request.id}.png")
|
||||||
})
|
external_qr_link = f'static/qr_codes/request_{service_request.id}.png'
|
||||||
|
|
||||||
|
if not os.path.exists(qr_code_dir):
|
||||||
|
os.makedirs(qr_code_dir)
|
||||||
|
|
||||||
|
qr.save(qr_code_path)
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
'registration_link': registration_link,
|
||||||
|
'qr_code_url': f"/{external_qr_link}",
|
||||||
|
'service_request_id': service_request.id
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405)
|
||||||
|
|
||||||
def complete_registration(request, request_id):
|
def complete_registration(request, request_id):
|
||||||
# Завершение регистрации по идентификатору заявки
|
# Завершение регистрации по идентификатору заявки
|
||||||
@@ -200,13 +281,6 @@ def complete_registration_basic(request):
|
|||||||
client_email = request.POST.get('client_email')
|
client_email = request.POST.get('client_email')
|
||||||
client_phone = request.POST.get('client_phone')
|
client_phone = request.POST.get('client_phone')
|
||||||
|
|
||||||
# # Создаем новую запись заявки
|
|
||||||
# service_request = ServiceRequest.objects.create(
|
|
||||||
# client_name=client_name,
|
|
||||||
# client_email=client_email,
|
|
||||||
# client_phone=client_phone
|
|
||||||
# )
|
|
||||||
|
|
||||||
return redirect('home')
|
return redirect('home')
|
||||||
|
|
||||||
return render(request, 'web/complete_registration_basic.html')
|
return render(request, 'web/complete_registration_basic.html')
|
||||||
|
|||||||