bnovo
This commit is contained in:
129
antifroud/migrations/0001_initial.py
Normal file
129
antifroud/migrations/0001_initial.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ExternalDBSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Имя подключения для идентификации.', max_length=255, unique=True)),
|
||||
('host', models.CharField(help_text='Адрес сервера базы данных.', max_length=255)),
|
||||
('port', models.PositiveIntegerField(default=3306, help_text='Порт сервера базы данных.')),
|
||||
('user', models.CharField(help_text='Имя пользователя базы данных.', max_length=255)),
|
||||
('password', models.CharField(help_text='Пароль для подключения.', max_length=255)),
|
||||
('database', models.CharField(default='u1510415_wp832', help_text='Имя базы данных.', max_length=255)),
|
||||
('table_name', models.CharField(blank=True, default='wpts_user_activity_log', help_text='Имя таблицы для загрузки данных.', max_length=255, null=True)),
|
||||
('selected_fields', models.TextField(blank=True, help_text='Список полей для загрузки (через запятую).', null=True)),
|
||||
('is_active', models.BooleanField(default=True, help_text='Флаг активности подключения.')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Настройка подключения к БД',
|
||||
'verbose_name_plural': 'Настройки подключений к БД',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ImportedHotel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('external_id', models.CharField(max_length=255, verbose_name='Внешний ID отеля')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Имя отеля')),
|
||||
('display_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Отображаемое имя')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')),
|
||||
('imported', models.BooleanField(default=False, verbose_name='Импортирован в основную базу')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Импортированный отель',
|
||||
'verbose_name_plural': 'Импортированные отели',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RoomDiscrepancy',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('room_number', models.CharField(max_length=50, verbose_name='Номер комнаты')),
|
||||
('booking_id', models.CharField(max_length=255, verbose_name='ID бронирования')),
|
||||
('check_in_date_expected', models.DateField(verbose_name='Ожидаемая дата заселения')),
|
||||
('check_in_date_actual', models.DateField(verbose_name='Фактическая дата заселения')),
|
||||
('discrepancy_type', models.CharField(choices=[('early', 'Раннее заселение'), ('late', 'Позднее заселение'), ('missed', 'Неявка')], max_length=50, verbose_name='Тип несоответствия')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Несовпадение в заселении',
|
||||
'verbose_name_plural': 'Несовпадения в заселении',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SyncLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now=True, verbose_name='Дата обновления')),
|
||||
('recieved_records', models.IntegerField(default=0, verbose_name='Полученные записи')),
|
||||
('processed_records', models.IntegerField(default=0, verbose_name='Обработанные записи')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Журнал синхронизации',
|
||||
'verbose_name_plural': 'Журналы синхронизации',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserActivityLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('external_id', models.CharField(db_index=True, max_length=255, unique=True, verbose_name='Внешний ID')),
|
||||
('user_id', models.BigIntegerField(blank=True, db_index=True, null=True, verbose_name='ID пользователя')),
|
||||
('ip', models.GenericIPAddressField(blank=True, db_index=True, null=True, verbose_name='IP-адрес')),
|
||||
('created', models.DateTimeField(blank=True, db_index=True, null=True, verbose_name='Дата создания')),
|
||||
('timestamp', models.BigIntegerField(blank=True, null=True, verbose_name='Метка времени')),
|
||||
('date_time', models.DateTimeField(blank=True, null=True, verbose_name='Дата и время')),
|
||||
('referred', models.TextField(blank=True, null=True, verbose_name='Реферальная ссылка')),
|
||||
('agent', models.TextField(blank=True, null=True, verbose_name='Агент пользователя')),
|
||||
('platform', models.CharField(blank=True, max_length=255, null=True, verbose_name='Платформа')),
|
||||
('version', models.CharField(blank=True, max_length=255, null=True, verbose_name='Версия')),
|
||||
('model', models.CharField(blank=True, max_length=255, null=True, verbose_name='Модель устройства')),
|
||||
('device', models.CharField(blank=True, max_length=255, null=True, verbose_name='Тип устройства')),
|
||||
('UAString', models.TextField(blank=True, null=True, verbose_name='User-Agent строка')),
|
||||
('location', models.CharField(blank=True, max_length=255, null=True, verbose_name='Местоположение')),
|
||||
('page_id', models.BigIntegerField(blank=True, db_index=True, null=True, verbose_name='ID страницы')),
|
||||
('url_parameters', models.TextField(blank=True, null=True, verbose_name='Параметры URL')),
|
||||
('page_title', models.TextField(blank=True, null=True, verbose_name='Заголовок страницы')),
|
||||
('type', models.CharField(blank=True, max_length=50, null=True, verbose_name='Тип')),
|
||||
('last_counter', models.IntegerField(blank=True, null=True, verbose_name='Последний счетчик')),
|
||||
('hits', models.IntegerField(blank=True, default='0', null=True, verbose_name='Количество обращений')),
|
||||
('honeypot', models.BooleanField(blank=True, null=True, verbose_name='Метка honeypot')),
|
||||
('reply', models.BooleanField(blank=True, null=True, verbose_name='Ответ пользователя')),
|
||||
('page_url', models.URLField(blank=True, null=True, verbose_name='URL страницы')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Регистрация посетителей',
|
||||
'verbose_name_plural': 'Регистрации посетителей',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ViolationLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('room_number', models.CharField(blank=True, max_length=50, null=True, verbose_name='Номер комнаты')),
|
||||
('violation_type', models.CharField(choices=[('missed', 'Неявка'), ('early', 'Раннее заселение'), ('late', 'Позднее заселение')], max_length=50, verbose_name='Тип нарушения')),
|
||||
('violation_details', models.TextField(blank=True, null=True, verbose_name='Детали нарушения')),
|
||||
('hits', models.IntegerField(verbose_name='Срабатывания')),
|
||||
('detected_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата обнаружения')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Журнал нарушений',
|
||||
'verbose_name_plural': 'Журналы нарушений',
|
||||
},
|
||||
),
|
||||
]
|
||||
32
antifroud/migrations/0002_initial.py
Normal file
32
antifroud/migrations/0002_initial.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('antifroud', '0001_initial'),
|
||||
('hotels', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='roomdiscrepancy',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='synclog',
|
||||
name='hotel',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='violationlog',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
]
|
||||
86
app_settings/migrations/0001_initial.py
Normal file
86
app_settings/migrations/0001_initial.py
Normal file
File diff suppressed because one or more lines are too long
138
hotels/migrations/0001_initial.py
Normal file
138
hotels/migrations/0001_initial.py
Normal file
File diff suppressed because one or more lines are too long
47
hotels/migrations/0002_initial.py
Normal file
47
hotels/migrations/0002_initial.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('hotels', '0001_initial'),
|
||||
('pms_integration', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='hotel',
|
||||
name='pms',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pms_integration.pmsconfiguration', verbose_name='PMS система'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='fraudlog',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frauds', to='hotels.hotel'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='reservation',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='guest',
|
||||
name='reservation',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='guests', to='hotels.reservation', verbose_name='Бронирование'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='room',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rooms', to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userhotel',
|
||||
name='hotel',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='hotel_users', to='hotels.hotel', verbose_name='Отель'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 05:10
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hotels', '0002_initial'),
|
||||
('users', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='hotel',
|
||||
old_name='external_id',
|
||||
new_name='external_id_pms',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='userhotel',
|
||||
name='user',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='user_hotels', to='users.user', verbose_name='Пользователь'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='apirequestlog',
|
||||
index=models.Index(fields=['api'], name='hotels_apir_api_id_686bb0_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='apirequestlog',
|
||||
index=models.Index(fields=['request_time'], name='hotels_apir_request_f65147_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fraudlog',
|
||||
index=models.Index(fields=['reservation_id'], name='hotels_frau_reserva_5a26b7_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='fraudlog',
|
||||
index=models.Index(fields=['detected_at'], name='hotels_frau_detecte_07e626_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='reservation',
|
||||
index=models.Index(fields=['hotel', 'check_in', 'check_out'], name='hotels_rese_hotel_i_6c527e_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='room',
|
||||
index=models.Index(fields=['hotel', 'number'], name='hotels_room_hotel_i_a7c4fc_idx'),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='room',
|
||||
constraint=models.UniqueConstraint(fields=('hotel', 'number'), name='unique_hotel_room'),
|
||||
),
|
||||
]
|
||||
50
pms_integration/migrations/0001_initial.py
Normal file
50
pms_integration/migrations/0001_initial.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('hotels', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PMSConfiguration',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Название PMS')),
|
||||
('url', models.URLField(verbose_name='URL API')),
|
||||
('token', models.CharField(blank=True, max_length=255, null=True, verbose_name='Токен')),
|
||||
('public_key', models.CharField(blank=True, max_length=255, null=True, verbose_name='Публичный ключ')),
|
||||
('private_key', models.CharField(blank=True, max_length=255, null=True, verbose_name='Приватный ключ')),
|
||||
('username', models.CharField(blank=True, max_length=255, null=True, verbose_name='Логин')),
|
||||
('password', models.CharField(blank=True, max_length=255, null=True, verbose_name='Пароль')),
|
||||
('plugin_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Плагин')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'PMS система',
|
||||
'verbose_name_plural': 'PMS системы',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PMSIntegrationLog',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('checked_at', models.DateTimeField(auto_now_add=True, verbose_name='Время проверки')),
|
||||
('status', models.CharField(choices=[('success', 'Успех'), ('error', 'Ошибка')], max_length=50, verbose_name='Статус')),
|
||||
('message', models.TextField(blank=True, null=True, verbose_name='Сообщение')),
|
||||
('hotel', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hotels.hotel', verbose_name='Отель')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Журнал интеграции PMS',
|
||||
'verbose_name_plural': 'Журналы интеграции PMS',
|
||||
'indexes': [models.Index(fields=['hotel'], name='pms_integra_hotel_i_ade4da_idx'), models.Index(fields=['checked_at'], name='pms_integra_checked_938acc_idx'), models.Index(fields=['status'], name='pms_integra_status_358b64_idx')],
|
||||
},
|
||||
),
|
||||
]
|
||||
19
pms_integration/migrations/0002_pmsconfiguration_hotels.py
Normal file
19
pms_integration/migrations/0002_pmsconfiguration_hotels.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 06:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('hotels', '0003_rename_external_id_hotel_external_id_pms_and_more'),
|
||||
('pms_integration', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='pmsconfiguration',
|
||||
name='hotels',
|
||||
field=models.ManyToManyField(related_name='pms_configurations', to='hotels.hotel', verbose_name='Отели'),
|
||||
),
|
||||
]
|
||||
116
pms_integration/plugins/travelline_pms.py
Normal file
116
pms_integration/plugins/travelline_pms.py
Normal file
@@ -0,0 +1,116 @@
|
||||
import logging
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from .base_plugin import BasePMSPlugin
|
||||
|
||||
class TravelLinePMSPlugin(BasePMSPlugin):
|
||||
"""
|
||||
Плагин для интеграции с PMS TravelLine.
|
||||
"""
|
||||
BASE_URL = "https://partner.tlintegration.com/api/webpms/v1"
|
||||
|
||||
def __init__(self, pms_config):
|
||||
"""
|
||||
Инициализация плагина с конфигурацией PMS.
|
||||
|
||||
:param pms_config: Конфигурация PMS (объект PMSConfiguration).
|
||||
"""
|
||||
super().__init__(pms_config)
|
||||
self.api_key = pms_config.token
|
||||
self.logger = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
def _get_headers(self):
|
||||
"""
|
||||
Возвращает заголовки для запросов.
|
||||
"""
|
||||
return {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
def _fetch_data(self):
|
||||
"""
|
||||
Получение данных из API TravelLine (поиск бронирований).
|
||||
|
||||
:return: Список номеров бронирований.
|
||||
"""
|
||||
url = f"{self.BASE_URL}/bookings"
|
||||
params = {
|
||||
"roomId": self.pms_config.room_id,
|
||||
"modifiedFrom": self.pms_config.modified_from,
|
||||
"modifiedTo": self.pms_config.modified_to,
|
||||
"state": self.pms_config.state,
|
||||
"affectsPeriodFrom": self.pms_config.affects_period_from,
|
||||
"affectsPeriodTo": self.pms_config.affects_period_to,
|
||||
}
|
||||
params = {k: v for k, v in params.items() if v is not None}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=self._get_headers(), params=params)
|
||||
response.raise_for_status()
|
||||
self.logger.info("Данные успешно получены из API TravelLine.")
|
||||
return response.json().get("bookingNumbers", [])
|
||||
except requests.RequestException as e:
|
||||
self.logger.error(f"Ошибка при запросе к API TravelLine: {e}")
|
||||
return []
|
||||
|
||||
def fetch_data(self):
|
||||
"""
|
||||
Обертка для получения данных из API TravelLine с дополнительной обработкой.
|
||||
|
||||
:return: Список номеров бронирований.
|
||||
"""
|
||||
return self._fetch_data()
|
||||
|
||||
def get_default_parser_settings(self):
|
||||
"""
|
||||
Возвращает настройки парсера по умолчанию.
|
||||
"""
|
||||
return {
|
||||
"field_mapping": {
|
||||
"reservation_id": "bookingNumber",
|
||||
"check_in": "actualCheckInDateTime",
|
||||
"check_out": "actualCheckOutDateTime",
|
||||
"room_number": "roomId",
|
||||
"status": "state",
|
||||
},
|
||||
"date_format": "%Y-%m-%dT%H:%M"
|
||||
}
|
||||
|
||||
def process_data(self, booking_number, room_stay_id, action, actual_date_time):
|
||||
"""
|
||||
Обработка данных для заселения или выселения проживания.
|
||||
|
||||
:param booking_number: Номер бронирования.
|
||||
:param room_stay_id: Идентификатор проживания.
|
||||
:param action: Действие ("check-in" или "check-out").
|
||||
:param actual_date_time: Фактические дата и время.
|
||||
:return: Ответ API.
|
||||
"""
|
||||
if action not in ["check-in", "check-out"]:
|
||||
raise ValueError("Invalid action. Must be 'check-in' or 'check-out'.")
|
||||
|
||||
url = f"{self.BASE_URL}/bookings/{booking_number}/room-stays/{room_stay_id}/{action}"
|
||||
payload = {
|
||||
f"actual{action.capitalize()}DateTime": actual_date_time
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, headers=self._get_headers(), json=payload)
|
||||
response.raise_for_status()
|
||||
self.logger.info(f"Успешно выполнено действие '{action}' для бронирования {booking_number}.")
|
||||
return response.json()
|
||||
except requests.RequestException as e:
|
||||
self.logger.error(f"Ошибка при выполнении действия '{action}': {e}")
|
||||
return {}
|
||||
|
||||
def validate_plugin(self):
|
||||
"""
|
||||
Проверка плагина на соответствие требованиям.
|
||||
"""
|
||||
required_methods = ["fetch_data", "get_default_parser_settings", "_fetch_data"]
|
||||
for method in required_methods:
|
||||
if not hasattr(self, method):
|
||||
raise ValueError(f"Плагин {type(self).__name__} не реализует метод {method}.")
|
||||
self.logger.info(f"Плагин {self.__class__.__name__} успешно прошел валидацию.")
|
||||
return True
|
||||
30
scheduler/migrations/0001_initial.py
Normal file
30
scheduler/migrations/0001_initial.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
import scheduler.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ScheduledTask',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('task_name', models.CharField(max_length=255, verbose_name='Название задачи')),
|
||||
('function_path', models.CharField(choices=scheduler.models.get_available_functions, max_length=500, verbose_name='Путь к функции (модуль.функция)')),
|
||||
('minutes', models.CharField(default='*', max_length=255, verbose_name='Минуты')),
|
||||
('hours', models.CharField(default='*', max_length=255, verbose_name='Часы')),
|
||||
('days', models.CharField(default='*', max_length=255, verbose_name='Дни')),
|
||||
('months', models.CharField(default='*', max_length=255, verbose_name='Месяцы')),
|
||||
('weekdays', models.JSONField(default=list, verbose_name='Дни недели')),
|
||||
('active', models.BooleanField(default=True, verbose_name='Активно')),
|
||||
('last_run', models.DateTimeField(blank=True, null=True, verbose_name='Последний запуск')),
|
||||
],
|
||||
),
|
||||
]
|
||||
63
users/migrations/0001_initial.py
Normal file
63
users/migrations/0001_initial.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# Generated by Django 5.1.4 on 2024-12-25 04:55
|
||||
|
||||
import django.contrib.auth.models
|
||||
import django.contrib.auth.validators
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='User',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
||||
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
|
||||
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
|
||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
||||
('telegram_id', models.BigIntegerField(blank=True, null=True, unique=True, verbose_name='ID Телеграм')),
|
||||
('chat_id', models.BigIntegerField(blank=True, null=True, unique=True, verbose_name='ID чата в телеграм')),
|
||||
('role', models.CharField(choices=[('admin', 'Администратор системы'), ('hotel_user', 'Сотрудник отеля')], default='hotel_user', max_length=20, verbose_name='Роль')),
|
||||
('confirmed', models.BooleanField(default=False, verbose_name='Подтвержден')),
|
||||
('groups', models.ManyToManyField(blank=True, related_name='custom_user_set', to='auth.group')),
|
||||
('user_permissions', models.ManyToManyField(blank=True, related_name='custom_user_set', to='auth.permission')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Пользователь',
|
||||
'verbose_name_plural': 'Пользователи',
|
||||
},
|
||||
managers=[
|
||||
('objects', django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='NotificationSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('telegram_enabled', models.BooleanField(default=True, verbose_name='Уведомления в Telegram')),
|
||||
('email_enabled', models.BooleanField(default=False, verbose_name='Уведомления по Email')),
|
||||
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email для уведомлений')),
|
||||
('notification_time', models.TimeField(default='09:00', verbose_name='Время отправки уведомлений')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='users.user', verbose_name='Пользователь')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Способ оповещения',
|
||||
'verbose_name_plural': 'Способы оповещений',
|
||||
},
|
||||
),
|
||||
]
|
||||
Reference in New Issue
Block a user