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

develop
Сергей Ванюшкин 2024-02-11 20:10:25 +03:00
parent 5a95b06300
commit 3dbefda936
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( @celery_app.task
'tasks', broker='amqp://guest:guest@localhost', backend='rpc://'
)
@celery_task_app.task
def periodic_task() -> None: def periodic_task() -> None:
result = loop.run_until_complete(main()) result = loop.run_until_complete(main())
return result return result

View File

@ -26,7 +26,7 @@ async def refresh_cache(disconts: dict):
await redis.flushall() await redis.flushall()
for key in disconts.keys(): 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))) 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 import redis.asyncio as redis # type: ignore
from fastapi import BackgroundTasks, Depends from fastapi import BackgroundTasks, Depends
from fastfood import models
from fastfood.dbase import get_async_redis_client from fastfood.dbase import get_async_redis_client
from fastfood.repository.dish import DishRepository from fastfood.repository.dish import DishRepository
from fastfood.repository.redis import RedisRepository, get_key from fastfood.repository.redis import RedisRepository, get_key
@ -21,6 +22,19 @@ class DishService:
self.bg_tasks = background_tasks self.bg_tasks = background_tasks
self.key = get_key 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]: async def read_dishes(self, menu_id: UUID, submenu_id: UUID) -> list[Dish]:
cached_dishes = await self.cache.get( cached_dishes = await self.cache.get(
self.key('dishes', menu_id=str(menu_id), submenu_id=str(submenu_id)) 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) data = await self.dish_repo.get_dishes(menu_id, submenu_id)
response = [] response = []
for row in data: for row in data:
dish = row.__dict__ dish = await self._convert_dish_to_dict(row)
dish['price'] = str(dish['price']) response.append(dish)
response.append(Dish(**dish))
await self.cache.set( await self.cache.set(
self.key( self.key(
'dishes', 'dishes',
@ -57,9 +71,7 @@ class DishService:
submenu_id, submenu_id,
dish_db, dish_db,
) )
dish = data.__dict__ dish = await self._convert_dish_to_dict(data)
dish['price'] = str(dish['price'])
dish = Dish(**dish)
await self.cache.set( await self.cache.set(
self.key('dish', menu_id=str(menu_id), submenu_id=str(submenu_id)), self.key('dish', menu_id=str(menu_id), submenu_id=str(submenu_id)),
dish, dish,
@ -86,9 +98,8 @@ class DishService:
data = await self.dish_repo.get_dish_item(menu_id, submenu_id, dish_id) data = await self.dish_repo.get_dish_item(menu_id, submenu_id, dish_id)
if data is None: if data is None:
return None return None
dish = data.__dict__ dish = await self._convert_dish_to_dict(data)
dish['price'] = str(dish['price'])
dish = Dish(**dish)
await self.cache.set( await self.cache.set(
self.key( self.key(
'dish', 'dish',
@ -112,9 +123,7 @@ class DishService:
if data is None: if data is None:
return None return None
dish = data.__dict__ dish = await self._convert_dish_to_dict(data)
dish['price'] = str(dish['price'])
dish = Dish(**dish)
await self.cache.set( await self.cache.set(
self.key( self.key(

View File

@ -20,29 +20,53 @@ class SummaryService:
self.bg_tasks = background_tasks self.bg_tasks = background_tasks
async def read_data(self): 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 = obj.__dict__
obj = {k: v for k, v in obj.items() if not k.startswith('_')} obj = {k: v for k, v in obj.items() if not k.startswith('_')}
if 'price' in obj.keys(): 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']) obj['price'] = str(obj['price'])
return schema(**obj) return schema(**obj)
cached_data = await self.cache.get(self.key('summary')) cached_data = await self.cache.get(self.key('summary'))
if cached_data is not None: if cached_data is not None:
return cached_data return cached_data
result = []
data = await self.sum_repo.get_data() data = await self.sum_repo.get_data()
for menu in data: for menu in data:
menus_res = dump_to_schema(MenuSummary, menu) menus_res = await dump_to_schema(MenuSummary, menu)
menus_res.submenus = [] menus_res.submenus = []
for sub in menu.submenus: for sub in menu.submenus:
sub_res = dump_to_schema(SubMenuSummary, sub) sub_res = await dump_to_schema(SubMenuSummary, sub)
sub_res.dishes = [] sub_res.dishes = []
for dish in sub.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) sub_res.dishes.append(dish_res)
menus_res.submenus.append(sub_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() 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']) 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']) 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) celery_beat_process = multiprocessing.Process(target=start_celery_beat)
async def run_app(): async def run_app() -> None:
""" """
Запуск FastAPI Запуск FastAPI
""" """
@ -36,7 +36,7 @@ async def run_app():
) )
async def recreate(): async def recreate() -> None:
"""Удаление и создание таблиц в базе данных для тестирования""" """Удаление и создание таблиц в базе данных для тестирования"""
await create_db_and_tables() await create_db_and_tables()