diff --git a/admin/Menu.xlsx b/admin/Menu.xlsx index ec412ae..ac02620 100644 Binary files a/admin/Menu.xlsx and b/admin/Menu.xlsx differ diff --git a/bg_tasks/bg_task.py b/bg_tasks/bg_task.py index 1ad4aba..c73b51e 100644 --- a/bg_tasks/bg_task.py +++ b/bg_tasks/bg_task.py @@ -22,12 +22,7 @@ celery_app.conf.beat_schedule = { } -celery_task_app = Celery( - 'tasks', broker='amqp://guest:guest@localhost', backend='rpc://' -) - - -@celery_task_app.task +@celery_app.task def periodic_task() -> None: result = loop.run_until_complete(main()) return result diff --git a/bg_tasks/updater.py b/bg_tasks/updater.py index d1cf1e1..339b434 100644 --- a/bg_tasks/updater.py +++ b/bg_tasks/updater.py @@ -26,7 +26,7 @@ async def refresh_cache(disconts: dict): await redis.flushall() for key in disconts.keys(): - await redis.set(f'DISCONT:{str(key)}', disconts[key]) + await redis.set(f'DISCONT:{str(key)}', pickle.dumps(disconts[key])) await redis.set('XLSX_MOD_TIME', pickle.dumps(os.path.getmtime(file))) diff --git a/fastfood/service/dish.py b/fastfood/service/dish.py index 689f4f0..981cf09 100644 --- a/fastfood/service/dish.py +++ b/fastfood/service/dish.py @@ -3,6 +3,7 @@ from uuid import UUID import redis.asyncio as redis # type: ignore from fastapi import BackgroundTasks, Depends +from fastfood import models from fastfood.dbase import get_async_redis_client from fastfood.repository.dish import DishRepository from fastfood.repository.redis import RedisRepository, get_key @@ -21,6 +22,19 @@ class DishService: self.bg_tasks = background_tasks self.key = get_key + async def _get_discont(self, dish) -> dict: + discont = await self.cache.get(f"DISCONT:{str(dish.get('id'))}") + if discont is not None: + discont = float(discont) + dish['price'] = round(dish['price'] - (dish['price'] * discont / 100), 2) + return dish + + async def _convert_dish_to_dict(self, row: models.Dish) -> Dish: + dish = row.__dict__ + dish = await self._get_discont(dish) + dish['price'] = str(dish['price']) + return Dish(**dish) + async def read_dishes(self, menu_id: UUID, submenu_id: UUID) -> list[Dish]: cached_dishes = await self.cache.get( self.key('dishes', menu_id=str(menu_id), submenu_id=str(submenu_id)) @@ -31,9 +45,9 @@ class DishService: data = await self.dish_repo.get_dishes(menu_id, submenu_id) response = [] for row in data: - dish = row.__dict__ - dish['price'] = str(dish['price']) - response.append(Dish(**dish)) + dish = await self._convert_dish_to_dict(row) + response.append(dish) + await self.cache.set( self.key( 'dishes', @@ -57,9 +71,7 @@ class DishService: submenu_id, dish_db, ) - dish = data.__dict__ - dish['price'] = str(dish['price']) - dish = Dish(**dish) + dish = await self._convert_dish_to_dict(data) await self.cache.set( self.key('dish', menu_id=str(menu_id), submenu_id=str(submenu_id)), dish, @@ -86,9 +98,8 @@ class DishService: data = await self.dish_repo.get_dish_item(menu_id, submenu_id, dish_id) if data is None: return None - dish = data.__dict__ - dish['price'] = str(dish['price']) - dish = Dish(**dish) + dish = await self._convert_dish_to_dict(data) + await self.cache.set( self.key( 'dish', @@ -112,9 +123,7 @@ class DishService: if data is None: return None - dish = data.__dict__ - dish['price'] = str(dish['price']) - dish = Dish(**dish) + dish = await self._convert_dish_to_dict(data) await self.cache.set( self.key( diff --git a/fastfood/service/summary.py b/fastfood/service/summary.py index 2c1a412..735c53f 100644 --- a/fastfood/service/summary.py +++ b/fastfood/service/summary.py @@ -20,29 +20,53 @@ class SummaryService: self.bg_tasks = background_tasks async def read_data(self): - def dump_to_schema(schema, obj): + + result = [] + + async def dump_to_schema( + schema, obj + ) -> MenuSummary | SubMenuSummary | DishBase: + """Функция преобразует объект SQLAlchemy к Pydantic модели + + Входящие параметры + schema: Pydantic модель + obj: ORM объект + + Возвращаемые данные + schema: MenuSummary | SubMenuSummary | DishBase + """ obj = obj.__dict__ obj = {k: v for k, v in obj.items() if not k.startswith('_')} + if 'price' in obj.keys(): + discont = await self.cache.get(f"DISCONT:{str(obj.get('id'))}") + + if discont is not None: + discont = float(discont) + obj['price'] = round( + obj['price'] - (obj['price'] * discont / 100), 2 + ) obj['price'] = str(obj['price']) + return schema(**obj) cached_data = await self.cache.get(self.key('summary')) + if cached_data is not None: return cached_data - result = [] data = await self.sum_repo.get_data() + for menu in data: - menus_res = dump_to_schema(MenuSummary, menu) + menus_res = await dump_to_schema(MenuSummary, menu) menus_res.submenus = [] for sub in menu.submenus: - sub_res = dump_to_schema(SubMenuSummary, sub) + sub_res = await dump_to_schema(SubMenuSummary, sub) sub_res.dishes = [] for dish in sub.dishes: - dish_res = dump_to_schema(DishBase, dish) + dish_res = await dump_to_schema(DishBase, dish) sub_res.dishes.append(dish_res) menus_res.submenus.append(sub_res) diff --git a/manage.py b/manage.py index a05d492..cb5762c 100644 --- a/manage.py +++ b/manage.py @@ -10,11 +10,11 @@ from fastfood.repository import create_db_and_tables loop = asyncio.get_event_loop() -def start_celery_worker(): +def start_celery_worker() -> None: Popen(['celery', '-A', 'bg_tasks.bg_task.celery_app', 'worker', '--loglevel=info']) -def start_celery_beat(): +def start_celery_beat() -> None: Popen(['celery', '-A', 'bg_tasks.bg_task.celery_app', 'beat', '--loglevel=info']) @@ -22,7 +22,7 @@ celery_worker_process = multiprocessing.Process(target=start_celery_worker) celery_beat_process = multiprocessing.Process(target=start_celery_beat) -async def run_app(): +async def run_app() -> None: """ Запуск FastAPI """ @@ -36,7 +36,7 @@ async def run_app(): ) -async def recreate(): +async def recreate() -> None: """Удаление и создание таблиц в базе данных для тестирования""" await create_db_and_tables()