From d808167639cfa13cff0840bcdf380195eaddef90 Mon Sep 17 00:00:00 2001 From: Oleg Oleg Date: Sat, 10 Jan 2026 21:35:28 +0400 Subject: [PATCH] meet doctor logic --- src/db/models.py | 15 ++++- .../handlers/doctors/meet_doctor_handler.py | 61 +++++++++++++------ 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/db/models.py b/src/db/models.py index a5d2c81..d8a7562 100644 --- a/src/db/models.py +++ b/src/db/models.py @@ -184,6 +184,7 @@ class NotificationType(enum.Enum): PAYMENT_RECEIVED = "payment_received" FIRST_REMINDER_SENT = "first_reminder_sent" + class SessionNotification(Base): __tablename__ = "session_notifications" __table_args__ = ( @@ -196,4 +197,16 @@ class SessionNotification(Base): type: Mapped[NotificationType] = mapped_column(nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) sent_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True) - last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True) \ No newline at end of file + last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True) + + +class TariffsSettings(Base): + __tablename__ = "tariffs_settings" + + id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) + name: Mapped[str] = mapped_column(String(100), unique=True, nullable=False) + description: Mapped[Optional[str]] = mapped_column(Text, nullable=True) + price: Mapped[Decimal] = mapped_column(Numeric(12, 2), nullable=False) + consultation_count: Mapped[int] = mapped_column(nullable=False) + duration_days: Mapped[int] = mapped_column(nullable=False) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) \ No newline at end of file diff --git a/src/docbot/handlers/doctors/meet_doctor_handler.py b/src/docbot/handlers/doctors/meet_doctor_handler.py index 015c16d..6bda2bb 100644 --- a/src/docbot/handlers/doctors/meet_doctor_handler.py +++ b/src/docbot/handlers/doctors/meet_doctor_handler.py @@ -6,9 +6,19 @@ from telegram.ext import ( CallbackQueryHandler ) from docbot.handlers.utils.cancel_handler import get_cancel_handler -from core.logging import logger -GET_TERMS_ACKNOWLEDGED = 1 + +START = 0 +TARIFF = 1 +LEGAL = 2 +WAIT_PAYMENT = 3 + + +TARIFFS = { + "tariff_novice": ("novice", 3990), + "tariff_unlimited": ("unlimited", 5990), +} + async def show_tariffs(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: @@ -16,39 +26,51 @@ async def show_tariffs(update: Update, context: ContextTypes.DEFAULT_TYPE) -> in [ InlineKeyboardButton( text="Тариф Новичок\n10 консультаций на месяц\n3990 рублей", - callback_data="tariff:ten:consultations", - url="https://pay.example.com/novice" + callback_data="tariff_novice" ), InlineKeyboardButton( text="Тариф Безлимит\n100 консультаций на месяц\n5990 рублей", - callback_data="tariff:hundred:consultations", - url="https://pay.example.com/beslimit" + callback_data="tariff_unlimited" ), ] ] await update.message.reply_text( text="Оплатить.\n\n" - "Юридический текст: для оказания услуг понадобятся ваши персональные данные:\n\n" - "фио, специальность и Telegram ID.\n\n" - "Нажимая кнопку оплатить, вы соглашаетесь с условиями оферты и обработкой персональных данных\n\n" - "на условиях Политики обработки перс данных (гиперссылка на оферту и Политику)", + "Юридический текст: для оказания услуг понадобятся ваши персональные данные:\n" + "фио, специальность и Telegram ID.\n\n" + "Нажимая кнопку оплатить, вы соглашаетесь с условиями оферты и обработкой персональных данных\n\n" + "на условиях Политики обработки перс данных (гиперссылка на оферту и Политику)\n\n" + "Бот обработает платеж в течение 10-20 минут и предложит вам регистрацию.\n" + "Чек придет вам на почту, если что-то пойдет не так - пишите @help_milana_in_law", parse_mode="Markdown", reply_markup=InlineKeyboardMarkup(keyboard_tariff) ) - return GET_TERMS_ACKNOWLEDGED + return START -async def send_notification(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: +async def choose_tariff(update: Update, context: ContextTypes.DEFAULT_TYPE): + query = update.callback_query + await query.answer() - await update.callback_query.message.reply_text( - text="Спасибо вам за доверие!\n\n" - "Бот обработает платеж в течение 10-20 минут и предложит вам регистрацию.\n\n" - "Чек придет вам на почту, если что-то пойдет не так - пишите @help_milana_in_law" + tariff, price = TARIFFS[query.data] + + await query.message.edit_text( + "\n\nНажмите «Оплатить».", ) + + payment_url = f"https://pay.example.com/payment?tariff={tariff}&price={price}" + pay_keyboard = [ + InlineKeyboardButton("Перейти к оплате", url=payment_url) + ] - return ConversationHandler.END + await query.message.reply_text( + "Перейдите к оплате:", + reply_markup=InlineKeyboardMarkup(pay_keyboard), + ) + + return WAIT_PAYMENT def meet_doctor_method() -> CommandHandler: @@ -60,9 +82,10 @@ def get_meet_doctor_handler() -> ConversationHandler: return ConversationHandler( entry_points=[meet_doctor_method()], states={ - GET_TERMS_ACKNOWLEDGED: [ - CallbackQueryHandler(send_notification, pattern="^(tariff)$") + START: [ + CallbackQueryHandler(choose_tariff, pattern="^tariff_") ], + WAIT_PAYMENT: [], }, fallbacks=[get_cancel_handler()], name="meet_doctor_handler",