from datetime import datetime, timedelta from aiogram import Router, F from aiogram.fsm.context import FSMContext from aiogram.types import Message, CallbackQuery, InlineKeyboardButton from aiogram.utils.keyboard import InlineKeyboardBuilder from logging import getLogger from ....main import QBotApp from ....model.descriptors import EntityFieldDescriptor, EntityDescriptor from ..context import ContextData, CallbackCommand from ..common import get_send_message, get_field_descriptor, get_entity_descriptor from .common import wrap_editor logger = getLogger(__name__) router = Router() async def date_picker(message: Message | CallbackQuery, field_descriptor: EntityFieldDescriptor, entity_descriptor: EntityDescriptor, callback_data: ContextData, current_value: datetime, state: FSMContext, edit_prompt: str | None = None, **kwargs): if not current_value: start_date = datetime.now() else: start_date = current_value start_date = start_date.replace(day = 1) previous_month = start_date - timedelta(days = 1) next_month = start_date.replace(day = 28) + timedelta(days = 4) keyboard_builder = InlineKeyboardBuilder() keyboard_builder.row(InlineKeyboardButton(text = "◀️", callback_data = ContextData( command = CallbackCommand.DATE_PICKER_MONTH, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = previous_month.strftime("%Y-%m-%d"), save_state = True).pack()), InlineKeyboardButton(text = start_date.strftime("%b %Y"), callback_data = ContextData( command = CallbackCommand.DATE_PICKER_YEAR, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = start_date.strftime("%Y-%m-%d"), save_state = True).pack()), InlineKeyboardButton(text = "▶️", callback_data = ContextData( command = CallbackCommand.DATE_PICKER_MONTH, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = next_month.strftime("%Y-%m-%d"), save_state = True).pack())) first_day = start_date - timedelta(days = start_date.weekday()) weeks = (((start_date.replace(day = 28) + timedelta(days = 4)).replace(day = 1) - first_day).days - 1) // 7 + 1 for week in range(weeks): buttons = [] for day in range(7): current_day = first_day + timedelta(days = week * 7 + day) buttons.append(InlineKeyboardButton(text = current_day.strftime("%d"), callback_data = ContextData( command = CallbackCommand.FIELD_EDITOR_CALLBACK, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = current_day.strftime("%Y-%m-%d"), save_state = True).pack())) keyboard_builder.row(*buttons) await wrap_editor(keyboard_builder = keyboard_builder, field_descriptor = field_descriptor, entity_descriptor = entity_descriptor, callback_data = callback_data, state = state) if edit_prompt: send_message = get_send_message(message) await send_message(text = edit_prompt, reply_markup = keyboard_builder.as_markup()) else: await message.edit_reply_markup(reply_markup = keyboard_builder.as_markup()) @router.callback_query(ContextData.filter(F.command == CallbackCommand.DATE_PICKER_YEAR)) async def date_picker_year(query: CallbackQuery, callback_data: ContextData, app: QBotApp, state: FSMContext, **kwargs): start_date = datetime.strptime(callback_data.data, "%Y-%m-%d") keyboard_builder = InlineKeyboardBuilder() keyboard_builder.row(InlineKeyboardButton(text = "🔼", callback_data = ContextData( command = CallbackCommand.DATE_PICKER_YEAR, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = start_date.replace(year = start_date.year - 20).strftime("%Y-%m-%d"), save_state = True).pack())) for r in range(4): buttons = [] for c in range(5): current_date = start_date.replace(year = start_date.year + r * 5 + c - 10) buttons.append(InlineKeyboardButton(text = current_date.strftime("%Y"), callback_data = ContextData( command = CallbackCommand.DATE_PICKER_MONTH, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = current_date.strftime("%Y-%m-%d"), save_state = True).pack())) keyboard_builder.row(*buttons) keyboard_builder.row(InlineKeyboardButton(text = "🔽", callback_data = ContextData( command = CallbackCommand.DATE_PICKER_YEAR, context = callback_data.context, entity_name = callback_data.entity_name, entity_id = callback_data.entity_id, field_name = callback_data.field_name, data = start_date.replace(year = start_date.year + 20).strftime("%Y-%m-%d"), save_state = True).pack())) field_descriptor = get_field_descriptor(app, callback_data) entity_descriptor = get_entity_descriptor(app, callback_data) await wrap_editor(keyboard_builder = keyboard_builder, field_descriptor = field_descriptor, entity_descriptor = entity_descriptor, callback_data = callback_data, state = state) await query.message.edit_reply_markup(reply_markup = keyboard_builder.as_markup()) @router.callback_query(ContextData.filter(F.command == CallbackCommand.DATE_PICKER_MONTH)) async def date_picker_month(query: CallbackQuery, callback_data: ContextData, app: QBotApp, **kwargs): entity_descriptor = get_entity_descriptor(app, callback_data) field_descriptor = get_field_descriptor(app, callback_data) await date_picker(query.message, field_descriptor = field_descriptor, entity_descriptor = entity_descriptor, callback_data = callback_data, current_value = datetime.strptime(callback_data.data, "%Y-%m-%d"), **kwargs)