upd: Применение скидки в выводе API

develop
Сергей Ванюшкин 2024-02-11 20:10:25 +03:00
parent d9633dcfbd
commit ffb5b855c4
6 changed files with 56 additions and 28 deletions

Binary file not shown.

View File

@ -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

View File

@ -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)))

View File

@ -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(

View File

@ -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)

View File

@ -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()