11"""Handlers for reports workflow."""
22
3+ import json
34import re
45from datetime import datetime
56from typing import Optional
@@ -35,6 +36,7 @@ class BooksState(StatesGroup):
3536 parent_category = State ()
3637 category = State ()
3738 category_title = State ()
39+ category_limit = State ()
3840
3941
4042class Books (HandlerBase ):
@@ -52,6 +54,7 @@ def __init__(self, db: models.DB, dp: Dispatcher, router: Router) -> None:
5254 router .callback_query .register (self .category_type_callback , BooksState .category_type )
5355 router .callback_query .register (self .categories_callback , BooksState .category )
5456 router .message .register (self .category_title_message , BooksState .category_title )
57+ dp .message .register (self .category_limit_message , BooksState .category_limit )
5558 dp .message .register (self .join , Command ('join' ))
5659
5760 async def books (
@@ -647,10 +650,10 @@ async def _categories(
647650 text = __ (messages .BUTTON_TITLE , lang = from_user .language_code ),
648651 callback_data = '/update_title'
649652 ),
650- # InlineKeyboardButton(
651- # text=__(messages.BUTTON_LIMIT, lang=from_user.language_code),
652- # callback_data='/set_limits '
653- # ),
653+ InlineKeyboardButton (
654+ text = __ (messages .BUTTON_LIMIT , lang = from_user .language_code ),
655+ callback_data = '/set_limit '
656+ ),
654657 InlineKeyboardButton (
655658 text = __ (messages .BUTTON_REMOVE , lang = from_user .language_code ),
656659 callback_data = '/delete'
@@ -711,10 +714,10 @@ async def categories_callback(self, call: CallbackQuery, state: FSMContext) -> N
711714 await state .update_data (category = data ['parent_category' ])
712715 await self .category_title (call .message , state , call .from_user )
713716 return
714- # if call.data == '/set_limits ':
715- # await state.update_data(category=data['parent_category'])
716- # await self.category_limits (call.message, state, call.from_user)
717- # return
717+ if call .data == '/set_limit ' :
718+ await state .update_data (category = data ['parent_category' ])
719+ await self .category_limit (call .message , state , call .from_user )
720+ return
718721 if call .data == '/delete' :
719722 category = self .db .get_category_by (
720723 book_id = book .id ,
@@ -764,21 +767,101 @@ async def categories_callback(self, call: CallbackQuery, state: FSMContext) -> N
764767 await state .update_data (parent_category = category_id )
765768 await self ._categories (call .message , state , call .from_user )
766769
767- # async def category_limits(
768- # self,
769- # message: Message,
770- # state: FSMContext,
771- # from_user: Optional[User] = None
772- # ) -> None:
773- # """Displays message to request category limits."""
774- # await state.set_state(BooksState.category_title)
775- # from_user = from_user or message.from_user
776- # await message.answer(
777- # text=__(
778- # text_dict=messages.CATEGORIES_SET_LIMITS,
779- # lang=from_user.language_code
780- # ).format(title=title),
781- # )
770+ async def category_limit (
771+ self ,
772+ message : Message ,
773+ state : FSMContext ,
774+ from_user : Optional [User ] = None
775+ ) -> None :
776+ """Displays message to request category limit."""
777+ await state .set_state (BooksState .category_limit )
778+ from_user = from_user or message .from_user
779+ data = await state .get_data ()
780+ book_id = int (data ['book' ])
781+ book = self .db .get_book_by (
782+ user_id = from_user .id ,
783+ id = book_id ,
784+ deleted = False
785+ )
786+ if not book :
787+ await self ._invalid_request (message , state )
788+ return
789+ parent_category = None
790+ if 'parent_category' in data :
791+ parent_category = self .db .get_category_by (
792+ book_id = book .id ,
793+ id = int (data ['parent_category' ]),
794+ category_type = data ['category_type' ],
795+ deleted = False
796+ )
797+ if not parent_category :
798+ await self ._invalid_request (message , state )
799+ return
800+ try :
801+ options = json .loads (parent_category .options )
802+ except Exception :
803+ options = {}
804+ monthly_limit = options .get ('monthly_limit' )
805+ if monthly_limit :
806+ monthly_limit_str = f'{ monthly_limit :.2f} { book .currency } '
807+ else :
808+ monthly_limit_str = __ (
809+ text_dict = messages .CATEGORIES_NO_LIMIT ,
810+ lang = from_user .language_code
811+ )
812+ await message .answer (
813+ text = __ (
814+ text_dict = messages .CATEGORIES_SET_LIMIT ,
815+ lang = from_user .language_code
816+ ).format (title = parent_category .title , limit = monthly_limit_str ),
817+ )
818+
819+ async def category_limit_message (self , message : Message , state : FSMContext ) -> None :
820+ """Handles entered category limit."""
821+ data = await state .get_data ()
822+ book_id = int (data ['book' ])
823+ book = self .db .get_book_by (
824+ user_id = message .from_user .id ,
825+ id = book_id ,
826+ deleted = False
827+ )
828+ if not book :
829+ await self ._invalid_request (message , state )
830+ return
831+ parent_category = None
832+ if 'parent_category' in data :
833+ parent_category = self .db .get_category_by (
834+ book_id = book .id ,
835+ id = int (data ['parent_category' ]),
836+ category_type = data ['category_type' ],
837+ deleted = False
838+ )
839+ if not parent_category :
840+ await self ._invalid_request (message , state )
841+ return
842+ amount_pattern = re .compile (r'^\d+\.{0,1}\d*$' )
843+ limit_str = message .text .strip ()
844+ if not amount_pattern .match (limit_str ):
845+ await message .answer (
846+ text = __ (
847+ text_dict = messages .CATEGORIES_LIMIT_INCORRECT ,
848+ lang = message .from_user .language_code
849+ ),
850+ )
851+ return
852+ try :
853+ options = json .loads (parent_category .options )
854+ except Exception :
855+ options = {}
856+ options ['monthly_limit' ] = float (limit_str )
857+ self .db .update_category (id = parent_category .id , options = json .dumps (options ))
858+ await message .answer (
859+ text = __ (
860+ text_dict = messages .CATEGORIES_LIMIT_UPDATED ,
861+ lang = message .from_user .language_code
862+ ),
863+ )
864+ await self ._categories (message , state , message .from_user )
782865
783866 async def category_title (
784867 self ,
0 commit comments