mirror of
https://github.com/olegvodyanov/docbot.git
synced 2025-12-20 08:07:04 +03:00
change tables, update doctor registration logic
This commit is contained in:
parent
2379e6e2a9
commit
414729c41f
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ db/
|
|||||||
!src/db
|
!src/db
|
||||||
__pycache__
|
__pycache__
|
||||||
src/docbot/conversations.pkl
|
src/docbot/conversations.pkl
|
||||||
|
conversations.pkl
|
||||||
7
src/core/enums/statuses_helpers.py
Normal file
7
src/core/enums/statuses_helpers.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectStatuses(str, Enum):
|
||||||
|
SENT = "Sent"
|
||||||
|
DECLINED = "Declined"
|
||||||
|
ACCEPTED = "Accepted"
|
||||||
9
src/core/utils.py
Normal file
9
src/core/utils.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def UUID_code_generator() -> str:
|
||||||
|
"""
|
||||||
|
Генерирует уникальный код в формате UUID.
|
||||||
|
Возвращает строку с кодом.
|
||||||
|
"""
|
||||||
|
return str(uuid.uuid4().hex[:8])
|
||||||
@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
||||||
from sqlalchemy import String, DateTime, Boolean, ForeignKey, Integer, UniqueConstraint
|
from sqlalchemy import String, ForeignKey
|
||||||
from sqlalchemy.dialects.postgresql import UUID, ARRAY
|
from sqlalchemy.dialects.postgresql import UUID, ARRAY
|
||||||
import uuid
|
import uuid
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
@ -14,41 +14,54 @@ class Base(DeclarativeBase):
|
|||||||
class SessionCode(Base):
|
class SessionCode(Base):
|
||||||
__tablename__ = "session_codes"
|
__tablename__ = "session_codes"
|
||||||
|
|
||||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id: Mapped[uuid.UUID] = mapped_column(
|
||||||
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
code: Mapped[str] = mapped_column(String(8), unique=True, nullable=False)
|
code: Mapped[str] = mapped_column(String(8), unique=True, nullable=False)
|
||||||
patient_telegram_id: Mapped[int] = mapped_column(nullable=False)
|
patient_telegram_id: Mapped[int] = mapped_column(nullable=False)
|
||||||
sent_at: Mapped[datetime] = mapped_column(nullable=False)
|
sent_at: Mapped[datetime] = mapped_column(nullable=False)
|
||||||
consulted_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
consulted_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
||||||
doctor_id: Mapped[Optional[uuid.UUID]] = mapped_column(UUID(as_uuid=True), ForeignKey("doctors.id"))
|
doctor_id: Mapped[Optional[uuid.UUID]] = mapped_column(
|
||||||
|
UUID(as_uuid=True), ForeignKey("doctors.id"))
|
||||||
|
|
||||||
|
|
||||||
class Admins(Base):
|
class Admins(Base):
|
||||||
__tablename__ = "admins"
|
__tablename__ = "admins"
|
||||||
|
|
||||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id: Mapped[uuid.UUID] = mapped_column(
|
||||||
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
telegram_id: Mapped[int] = mapped_column(unique=True, nullable=False)
|
telegram_id: Mapped[int] = mapped_column(unique=True, nullable=False)
|
||||||
created_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
created_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
||||||
available_payment_methods: Mapped[Optional[List[str]]] = mapped_column(ARRAY(String), nullable=True)
|
available_payment_methods: Mapped[Optional[List[str]]] = mapped_column(
|
||||||
|
ARRAY(String), nullable=True)
|
||||||
|
|
||||||
|
|
||||||
class Doctors(Base):
|
class Doctors(Base):
|
||||||
__tablename__ = "doctors"
|
__tablename__ = "doctors"
|
||||||
|
|
||||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
id: Mapped[uuid.UUID] = mapped_column(
|
||||||
|
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||||
telegram_id: Mapped[int] = mapped_column(unique=True, nullable=False)
|
telegram_id: Mapped[int] = mapped_column(unique=True, nullable=False)
|
||||||
code: Mapped[str] = mapped_column(String(8), unique=True, nullable=False)
|
|
||||||
name: Mapped[str] = mapped_column(nullable=False)
|
name: Mapped[str] = mapped_column(nullable=False)
|
||||||
available_formats: Mapped[Optional[List[str]]] = mapped_column(ARRAY(String), nullable=True)
|
available_formats: Mapped[Optional[List[str]]
|
||||||
|
] = mapped_column(ARRAY(String), nullable=True)
|
||||||
is_active: Mapped[bool] = mapped_column(default=False, nullable=False)
|
is_active: Mapped[bool] = mapped_column(default=False, nullable=False)
|
||||||
is_verified: Mapped[bool] = mapped_column(default=False, nullable=False)
|
is_verified: Mapped[bool] = mapped_column(default=False, nullable=False)
|
||||||
created_at: Mapped[datetime] = mapped_column(nullable=False)
|
created_at: Mapped[datetime] = mapped_column(nullable=False)
|
||||||
referral_code_id: Mapped[int] = mapped_column(ForeignKey("referral_codes.id"), nullable=False)
|
referral_code_id: Mapped[int] = mapped_column(
|
||||||
specialties: Mapped[List[str]] = mapped_column(ARRAY(String), nullable=False, default=list)
|
ForeignKey("referral_codes.id"), nullable=False)
|
||||||
|
specialties: Mapped[List[str]] = mapped_column(
|
||||||
|
ARRAY(String), nullable=False, default=list)
|
||||||
|
|
||||||
referral: Mapped["ReferralCode"] = relationship(back_populates="doctor", uselist=False)
|
referral: Mapped["ReferralCode"] = relationship(
|
||||||
|
back_populates="doctor", uselist=False)
|
||||||
session_codes: Mapped[List["SessionCode"]] = relationship()
|
session_codes: Mapped[List["SessionCode"]] = relationship()
|
||||||
form_links: Mapped[List["FormLink"]] = relationship(back_populates="doctor", cascade="all, delete-orphan")
|
form_links: Mapped[List["FormLink"]] = relationship(
|
||||||
payment_methods: Mapped[List["PaymentMethod"]] = relationship(back_populates="doctor", cascade="all, delete-orphan")
|
back_populates="doctor", cascade="all, delete-orphan")
|
||||||
|
payment_methods: Mapped[List["PaymentMethod"]] = relationship(
|
||||||
|
back_populates="doctor", cascade="all, delete-orphan")
|
||||||
|
verification_requests: Mapped[List["VerificationRequests"]] = relationship(
|
||||||
|
back_populates="doctor", cascade="all, delete-orphan")
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<Doctors(telegram_id={self.telegram_id!r})>"
|
return f"<Doctors(telegram_id={self.telegram_id!r})>"
|
||||||
@ -62,7 +75,8 @@ class ReferralCode(Base):
|
|||||||
is_used: Mapped[bool] = mapped_column(default=False, nullable=False)
|
is_used: Mapped[bool] = mapped_column(default=False, nullable=False)
|
||||||
created_at: Mapped[datetime] = mapped_column(nullable=False)
|
created_at: Mapped[datetime] = mapped_column(nullable=False)
|
||||||
used_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
used_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
||||||
doctor: Mapped[Optional["Doctors"]] = relationship(back_populates="referral", uselist=False)
|
doctor: Mapped[Optional["Doctors"]] = relationship(
|
||||||
|
back_populates="referral", uselist=False)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<ReferralCode(code={self.code!r}, is_used={self.is_used})>"
|
return f"<ReferralCode(code={self.code!r}, is_used={self.is_used})>"
|
||||||
@ -72,12 +86,14 @@ class VerificationRequests(Base):
|
|||||||
__tablename__ = "verification_requests"
|
__tablename__ = "verification_requests"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("doctors.id", ondelete="CASCADE"), nullable=False)
|
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey(
|
||||||
|
"doctors.id", ondelete="CASCADE"), nullable=False)
|
||||||
code: Mapped[str] = mapped_column(unique=True, nullable=False)
|
code: Mapped[str] = mapped_column(unique=True, nullable=False)
|
||||||
sent_at: Mapped[datetime] = mapped_column(nullable=False)
|
sent_at: Mapped[datetime] = mapped_column(nullable=False)
|
||||||
reviewed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
reviewed_at: Mapped[Optional[datetime]] = mapped_column(nullable=True)
|
||||||
|
status: Mapped[str] = mapped_column(default=False, nullable=False)
|
||||||
# Связь поправлена — связь с doctor через doctor_id
|
# Связь поправлена — связь с doctor через doctor_id
|
||||||
doctor: Mapped["Doctors"] = relationship()
|
doctor: Mapped["Doctors"] = relationship(back_populates="verification_requests")
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<VerificationRequests(code={self.code!r})>"
|
return f"<VerificationRequests(code={self.code!r})>"
|
||||||
@ -87,7 +103,8 @@ class FormLink(Base):
|
|||||||
__tablename__ = "form_links"
|
__tablename__ = "form_links"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("doctors.id", ondelete="CASCADE"), nullable=False)
|
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey(
|
||||||
|
"doctors.id", ondelete="CASCADE"), nullable=False)
|
||||||
url: Mapped[str] = mapped_column(nullable=False)
|
url: Mapped[str] = mapped_column(nullable=False)
|
||||||
label: Mapped[Optional[str]] = mapped_column(nullable=True)
|
label: Mapped[Optional[str]] = mapped_column(nullable=True)
|
||||||
is_active: Mapped[bool] = mapped_column(default=True, nullable=False)
|
is_active: Mapped[bool] = mapped_column(default=True, nullable=False)
|
||||||
@ -100,7 +117,8 @@ class PaymentMethod(Base):
|
|||||||
__tablename__ = "payment_methods"
|
__tablename__ = "payment_methods"
|
||||||
|
|
||||||
id: Mapped[int] = mapped_column(primary_key=True)
|
id: Mapped[int] = mapped_column(primary_key=True)
|
||||||
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("doctors.id", ondelete="CASCADE"), nullable=False)
|
doctor_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey(
|
||||||
|
"doctors.id", ondelete="CASCADE"), nullable=False)
|
||||||
method: Mapped[str] = mapped_column(nullable=False)
|
method: Mapped[str] = mapped_column(nullable=False)
|
||||||
details: Mapped[Optional[str]] = mapped_column(nullable=True)
|
details: Mapped[Optional[str]] = mapped_column(nullable=True)
|
||||||
is_active: Mapped[bool] = mapped_column(default=True, nullable=False)
|
is_active: Mapped[bool] = mapped_column(default=True, nullable=False)
|
||||||
|
|||||||
@ -8,8 +8,10 @@ from telegram.ext import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from docbot.handlers.utils.cancel_handler import get_cancel_handler
|
from docbot.handlers.utils.cancel_handler import get_cancel_handler
|
||||||
from docbot.services.referral_service import validate_referral_code, mark_referral_code_as_used
|
from docbot.services.referral_service import validate_referral_code
|
||||||
|
from docbot.services.doctors_service import create_doctor
|
||||||
from core.enums.dialog_helpers import ConfirmationMessage, Acknowledgement
|
from core.enums.dialog_helpers import ConfirmationMessage, Acknowledgement
|
||||||
|
from core.utils import UUID_code_generator
|
||||||
|
|
||||||
ASK_REFERRAL_CODE = 1
|
ASK_REFERRAL_CODE = 1
|
||||||
SEND_ACKNOWLEDGEMENT_INFO = 2
|
SEND_ACKNOWLEDGEMENT_INFO = 2
|
||||||
@ -32,7 +34,7 @@ SEND_ME_YOUR_SPECIALITY_TEXT = (
|
|||||||
"📝 Пожалуйста, введите вашу специальность, в соответствии с которой планируете проводить консультации."
|
"📝 Пожалуйста, введите вашу специальность, в соответствии с которой планируете проводить консультации."
|
||||||
)
|
)
|
||||||
WAIT_FOR_ACTIVATION_TEXT = (
|
WAIT_FOR_ACTIVATION_TEXT = (
|
||||||
"📝 Заявка принята, направьте диплом и аккредитацию с указанием кода в теме письма на адрес электронной почты:____\n"
|
"📝 Заявка принята, направьте диплом и аккредитацию с указанием кода верификации {0} в теме письма на адрес электронной почты: docbot@docbot.ru\n"
|
||||||
"В этом шаге нужно встроить подсказку: в каком формате направлять диплом, как скачать с госуслуг\n"
|
"В этом шаге нужно встроить подсказку: в каком формате направлять диплом, как скачать с госуслуг\n"
|
||||||
"выписку об аккредитации. Верификация займет 24 часа."
|
"выписку об аккредитации. Верификация займет 24 часа."
|
||||||
)
|
)
|
||||||
@ -82,7 +84,7 @@ async def receive_doctor_referral_code(update: Update, context: ContextTypes.DEF
|
|||||||
async def receive_doctor_info_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
async def receive_doctor_info_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||||
doctor_info_confirmation = update.message.text.strip()
|
doctor_info_confirmation = update.message.text.strip()
|
||||||
|
|
||||||
if doctor_info_confirmation == ConfirmationMessage.DECLINE.value:
|
if doctor_info_confirmation != ConfirmationMessage.PROCEED.value:
|
||||||
return ConversationHandler.END
|
return ConversationHandler.END
|
||||||
|
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
@ -114,8 +116,11 @@ async def receive_doctor_speciality(update: Update, context: ContextTypes.DEFAUL
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
code = UUID_code_generator()
|
||||||
|
context.user_data["verification_request_code"] = code
|
||||||
|
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
WAIT_FOR_ACTIVATION_TEXT,
|
WAIT_FOR_ACTIVATION_TEXT.format(code),
|
||||||
parse_mode="Markdown",
|
parse_mode="Markdown",
|
||||||
reply_markup=ReplyKeyboardMarkup(
|
reply_markup=ReplyKeyboardMarkup(
|
||||||
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Отправка пакета документов"
|
reply_keyboard, one_time_keyboard=True, input_field_placeholder="Отправка пакета документов"
|
||||||
@ -160,10 +165,11 @@ async def receive_doctor_consultation_packages_acknowledgement_status(update: Up
|
|||||||
parse_mode="Markdown"
|
parse_mode="Markdown"
|
||||||
)
|
)
|
||||||
|
|
||||||
await mark_referral_code_as_used(
|
await create_doctor(
|
||||||
context.user_data["ref_obj"],
|
context.user_data["ref_obj"],
|
||||||
context.user_data["doctor_telegram_id"],
|
context.user_data["doctor_telegram_id"],
|
||||||
context.user_data["doctor_name"]
|
context.user_data["doctor_name"],
|
||||||
|
context.user_data["verification_request_code"]
|
||||||
)
|
)
|
||||||
return ConversationHandler.END
|
return ConversationHandler.END
|
||||||
|
|
||||||
@ -178,19 +184,24 @@ def get_register_doctor_first_stage_handler() -> ConversationHandler:
|
|||||||
entry_points=[ask_doctor_info_handler()],
|
entry_points=[ask_doctor_info_handler()],
|
||||||
states={
|
states={
|
||||||
ASK_REFERRAL_CODE: [
|
ASK_REFERRAL_CODE: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_referral_code)
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
receive_doctor_referral_code)
|
||||||
],
|
],
|
||||||
SEND_ACKNOWLEDGEMENT_INFO: [
|
SEND_ACKNOWLEDGEMENT_INFO: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_info_confirmation)
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
receive_doctor_info_confirmation)
|
||||||
],
|
],
|
||||||
ASK_NAME: [
|
ASK_NAME: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_name)
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
receive_doctor_name)
|
||||||
],
|
],
|
||||||
ASK_SPECIALITY: [
|
ASK_SPECIALITY: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_speciality)
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
receive_doctor_speciality)
|
||||||
],
|
],
|
||||||
SEND_DIPLOMA_ACK_INFO: [
|
SEND_DIPLOMA_ACK_INFO: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND, receive_doctor_diploma_acknowledgement_status)
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
receive_doctor_diploma_acknowledgement_status)
|
||||||
],
|
],
|
||||||
SEND_CONSULTATION_TYPE_ACK_INFO: [
|
SEND_CONSULTATION_TYPE_ACK_INFO: [
|
||||||
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
MessageHandler(filters.TEXT & ~filters.COMMAND,
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
from telegram import Update, ReplyKeyboardMarkup
|
from telegram import Update, ReplyKeyboardMarkup
|
||||||
from telegram.ext import ContextTypes
|
from telegram.ext import ContextTypes, CommandHandler
|
||||||
|
|
||||||
from docbot.services.admins_service import get_admin_info
|
from docbot.services.admins_service import get_admin_info
|
||||||
from docbot.services.doctors_service import get_doctor_info
|
from docbot.services.doctors_service import get_doctor_info
|
||||||
|
|
||||||
|
|
||||||
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
"""
|
"""
|
||||||
Отдаёт список команд, доступных текущему пользователю:
|
Отдаёт список команд, доступных текущему пользователю:
|
||||||
@ -58,3 +59,10 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> No
|
|||||||
resize_keyboard=True
|
resize_keyboard=True
|
||||||
)
|
)
|
||||||
await update.message.reply_text(text, parse_mode="Markdown", reply_markup=keyboard)
|
await update.message.reply_text(text, parse_mode="Markdown", reply_markup=keyboard)
|
||||||
|
|
||||||
|
|
||||||
|
def get_help_handler() -> CommandHandler:
|
||||||
|
"""
|
||||||
|
Возвращает хэндлер для команды /help.
|
||||||
|
"""
|
||||||
|
return CommandHandler("help", help_command)
|
||||||
|
|||||||
@ -7,6 +7,7 @@ from docbot.handlers.patients.send_form_handler import get_send_form_handler
|
|||||||
from docbot.handlers.admins.doctors_handler import get_doctors_handler
|
from docbot.handlers.admins.doctors_handler import get_doctors_handler
|
||||||
from docbot.handlers.doctors.register_handler import get_register_doctor_first_stage_handler
|
from docbot.handlers.doctors.register_handler import get_register_doctor_first_stage_handler
|
||||||
from docbot.handlers.admins.generate_ref import get_referral_handlers
|
from docbot.handlers.admins.generate_ref import get_referral_handlers
|
||||||
|
from docbot.handlers.utils.help import get_help_handler
|
||||||
from docbot.handlers.utils.unknown import get_unknown_handler
|
from docbot.handlers.utils.unknown import get_unknown_handler
|
||||||
|
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ def main():
|
|||||||
app.add_handler(get_doctors_handler())
|
app.add_handler(get_doctors_handler())
|
||||||
app.add_handler(get_register_doctor_first_stage_handler())
|
app.add_handler(get_register_doctor_first_stage_handler())
|
||||||
app.add_handler(get_referral_handlers())
|
app.add_handler(get_referral_handlers())
|
||||||
|
app.add_handler(get_help_handler())
|
||||||
app.add_handler(get_unknown_handler())
|
app.add_handler(get_unknown_handler())
|
||||||
logger.debug("Все хэндлеры зарегистрированы, запускаем polling")
|
logger.debug("Все хэндлеры зарегистрированы, запускаем polling")
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ async def get_admin_info(telegram_id: int) -> Admins | None:
|
|||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(Admins.telegram_id)
|
select(Admins.telegram_id)
|
||||||
.where(Admins.telegram_id.match(telegram_id))
|
.where(Admins.telegram_id == telegram_id)
|
||||||
)
|
)
|
||||||
return result.scalar_one_or_none()
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
@ -18,6 +18,6 @@ async def mark_doctor_inactive(telegram_id: int) -> Admins | None:
|
|||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(Admins.telegram_id)
|
select(Admins.telegram_id)
|
||||||
.where(Admins.telegram_id.match(telegram_id))
|
.where(Admins.telegram_id == telegram_id)
|
||||||
)
|
)
|
||||||
return result.scalar_one_or_none()
|
return result.scalar_one_or_none()
|
||||||
@ -5,15 +5,16 @@ from datetime import datetime
|
|||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|
||||||
from db.session import AsyncSessionLocal
|
from db.session import AsyncSessionLocal
|
||||||
from db.models import Doctors
|
from db.models import Doctors, VerificationRequests, ReferralCode
|
||||||
from core.enums.consultation_types import Consultation
|
from core.enums.consultation_types import Consultation
|
||||||
|
from core.enums.statuses_helpers import ObjectStatuses
|
||||||
|
|
||||||
|
|
||||||
async def get_doctor_info(telegram_id: int) -> Doctors | None:
|
async def get_doctor_info(telegram_id: int) -> Doctors | None:
|
||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(Doctors)
|
select(Doctors)
|
||||||
.where(Doctors.telegram_id.match(telegram_id))
|
.where(Doctors.telegram_id == telegram_id)
|
||||||
)
|
)
|
||||||
return result.scalar_one_or_none()
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
@ -37,3 +38,35 @@ async def add_doctor(telegram_id: int, name: str, available_formats: Consultatio
|
|||||||
is_active=is_active,
|
is_active=is_active,
|
||||||
created_at=datetime.utcnow()
|
created_at=datetime.utcnow()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
async def create_doctor(referral_obj: ReferralCode, telegram_id: int, name: str, verification_code: str) -> Doctors:
|
||||||
|
"""
|
||||||
|
Помечает referral_obj как использованный, создаёт запись в таблице Doctors
|
||||||
|
с привязкой к telegram_id и возвращает объект Doctor.
|
||||||
|
"""
|
||||||
|
async with AsyncSessionLocal() as session:
|
||||||
|
async with session.begin():
|
||||||
|
# помечаем код
|
||||||
|
referral_obj.is_used = True
|
||||||
|
referral_obj.used_at = datetime.utcnow()
|
||||||
|
|
||||||
|
# создаём врача
|
||||||
|
new_doc = Doctors(
|
||||||
|
telegram_id=telegram_id,
|
||||||
|
name=name,
|
||||||
|
is_active=False,
|
||||||
|
created_at=datetime.utcnow(),
|
||||||
|
referral=referral_obj
|
||||||
|
)
|
||||||
|
|
||||||
|
verification_request = VerificationRequests()
|
||||||
|
verification_request.code = verification_code
|
||||||
|
verification_request.requested_at = datetime.utcnow()
|
||||||
|
verification_request.status = ObjectStatuses.SENT.value
|
||||||
|
verification_request.doctor = new_doc
|
||||||
|
verification_request.sent_at = datetime.utcnow()
|
||||||
|
session.add(verification_request)
|
||||||
|
session.add(new_doc)
|
||||||
|
await session.commit()
|
||||||
|
return new_doc
|
||||||
|
|||||||
@ -15,7 +15,8 @@ async def generate_referral_code(length: int = 12) -> str:
|
|||||||
"""
|
"""
|
||||||
alphabet = string.ascii_uppercase + string.digits
|
alphabet = string.ascii_uppercase + string.digits
|
||||||
while True:
|
while True:
|
||||||
referral_code = "".join(secrets.choice(alphabet) for _ in range(length))
|
referral_code = "".join(secrets.choice(alphabet)
|
||||||
|
for _ in range(length))
|
||||||
async with AsyncSessionLocal() as session:
|
async with AsyncSessionLocal() as session:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(ReferralCode)
|
select(ReferralCode)
|
||||||
@ -23,7 +24,8 @@ async def generate_referral_code(length: int = 12) -> str:
|
|||||||
)
|
)
|
||||||
exists = result.scalar_one_or_none()
|
exists = result.scalar_one_or_none()
|
||||||
if not exists:
|
if not exists:
|
||||||
new_ref = ReferralCode(code=referral_code, created_at=datetime.utcnow())
|
new_ref = ReferralCode(
|
||||||
|
code=referral_code, created_at=datetime.utcnow())
|
||||||
session.add(new_ref)
|
session.add(new_ref)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
return referral_code
|
return referral_code
|
||||||
@ -43,28 +45,3 @@ async def validate_referral_code(referral_code: str) -> ReferralCode | None:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
return result.scalar_one_or_none()
|
return result.scalar_one_or_none()
|
||||||
|
|
||||||
|
|
||||||
async def mark_referral_code_as_used(referral_obj: ReferralCode, telegram_id: int, name: str) -> Doctors:
|
|
||||||
"""
|
|
||||||
Помечает referral_obj как использованный, создаёт запись в таблице Doctors
|
|
||||||
с привязкой к telegram_id и возвращает объект Doctor.
|
|
||||||
"""
|
|
||||||
async with AsyncSessionLocal() as session:
|
|
||||||
async with session.begin():
|
|
||||||
# помечаем код
|
|
||||||
referral_obj.is_used = True
|
|
||||||
referral_obj.used_at = datetime.utcnow()
|
|
||||||
|
|
||||||
# создаём врача
|
|
||||||
new_doc = Doctors(
|
|
||||||
telegram_id=telegram_id,
|
|
||||||
name=name,
|
|
||||||
is_active=False,
|
|
||||||
created_at=datetime.utcnow(),
|
|
||||||
referral=referral_obj
|
|
||||||
)
|
|
||||||
session.add(new_doc)
|
|
||||||
await session.commit()
|
|
||||||
return new_doc
|
|
||||||
|
|
||||||
|
|||||||
@ -7,15 +7,16 @@ from sqlalchemy import select
|
|||||||
|
|
||||||
from db.session import AsyncSessionLocal
|
from db.session import AsyncSessionLocal
|
||||||
from db.models import SessionCode
|
from db.models import SessionCode
|
||||||
|
from core.utils import UUID_code_generator
|
||||||
|
|
||||||
|
|
||||||
async def create_session_code(telegram_id: int, form_link: str) -> str:
|
async def create_session_code(telegram_id: int, form_link: str) -> str:
|
||||||
"""
|
"""
|
||||||
Генерирует уникальный код, сохраняет его вместе с Telegram ID и ссылкой на анкету.
|
Генерирует уникальный код, сохраняет его вместе с Telegram ID.
|
||||||
Возвращает этот код.
|
Возвращает этот код.
|
||||||
"""
|
"""
|
||||||
code = uuid.uuid4().hex[:8]
|
code = UUID_code_generator()
|
||||||
async with AsyncSessionLocal() as session: # безопасно создаём сессию
|
async with AsyncSessionLocal() as session:
|
||||||
async with session.begin():
|
async with session.begin():
|
||||||
session.add(SessionCode(
|
session.add(SessionCode(
|
||||||
code=code,
|
code=code,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user