upd: Применение скидки в выводе API
parent
d9633dcfbd
commit
ffb5b855c4
BIN
admin/Menu.xlsx
BIN
admin/Menu.xlsx
Binary file not shown.
|
@ -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
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue