157 lines
6 KiB
Python
157 lines
6 KiB
Python
# app/routes/partners.py
|
||
"""
|
||
Маршруты API для управления партнерами
|
||
Соответствует модулям 1-3 ТЗ
|
||
"""
|
||
from fastapi import APIRouter, HTTPException
|
||
from app.database import db
|
||
from app.models import Partner, PartnerCreate, PartnerUpdate, DiscountResponse
|
||
from decimal import Decimal
|
||
|
||
router = APIRouter()
|
||
|
||
@router.get("/")
|
||
async def get_partners():
|
||
"""
|
||
Получение списка всех партнеров
|
||
Соответствует требованию просмотра списка партнеров
|
||
"""
|
||
try:
|
||
result = db.execute_query("""
|
||
SELECT partner_id, partner_type, company_name, legal_address,
|
||
inn, director_name, phone, email, rating, sales_locations
|
||
FROM partners
|
||
ORDER BY company_name
|
||
""")
|
||
|
||
partners_list = []
|
||
for row in result:
|
||
partner_dict = dict(row)
|
||
# Преобразуем рейтинг к int если нужно
|
||
if isinstance(partner_dict.get('rating'), float):
|
||
partner_dict['rating'] = int(partner_dict['rating'])
|
||
partners_list.append(partner_dict)
|
||
|
||
return partners_list
|
||
|
||
except Exception as e:
|
||
if "relation \"partners\" does not exist" in str(e):
|
||
return []
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.get("/{partner_id}")
|
||
async def get_partner(partner_id: int):
|
||
"""Получение информации о конкретном партнере"""
|
||
try:
|
||
result = db.execute_query(
|
||
"SELECT * FROM partners WHERE partner_id = %s",
|
||
(partner_id,)
|
||
)
|
||
if not result:
|
||
raise HTTPException(status_code=404, detail="Partner not found")
|
||
|
||
partner_data = dict(result[0])
|
||
# Преобразуем рейтинг к int если нужно
|
||
if isinstance(partner_data.get('rating'), float):
|
||
partner_data['rating'] = int(partner_data['rating'])
|
||
|
||
return partner_data
|
||
|
||
except Exception as e:
|
||
if "relation \"partners\" does not exist" in str(e):
|
||
raise HTTPException(status_code=404, detail="Partner not found")
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.post("/")
|
||
async def create_partner(partner: PartnerCreate):
|
||
"""
|
||
Создание нового партнера
|
||
Включает валидацию данных согласно ТЗ
|
||
"""
|
||
try:
|
||
result = db.execute_query("""
|
||
INSERT INTO partners
|
||
(partner_type, company_name, legal_address, inn, director_name,
|
||
phone, email, rating, sales_locations)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||
RETURNING partner_id
|
||
""", (
|
||
partner.partner_type, partner.company_name, partner.legal_address,
|
||
partner.inn, partner.director_name, partner.phone, partner.email,
|
||
partner.rating, partner.sales_locations
|
||
))
|
||
return {"partner_id": result[0]["partner_id"]}
|
||
except Exception as e:
|
||
if "duplicate key value violates unique constraint" in str(e):
|
||
raise HTTPException(status_code=400, detail="Partner with this INN already exists")
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.put("/{partner_id}")
|
||
async def update_partner(partner_id: int, partner: PartnerUpdate):
|
||
"""
|
||
Обновление данных партнера
|
||
Соответствует требованию редактирования данных партнера
|
||
"""
|
||
try:
|
||
db.execute_query("""
|
||
UPDATE partners SET
|
||
partner_type = %s, company_name = %s, legal_address = %s,
|
||
inn = %s, director_name = %s, phone = %s, email = %s,
|
||
rating = %s, sales_locations = %s
|
||
WHERE partner_id = %s
|
||
""", (
|
||
partner.partner_type, partner.company_name, partner.legal_address,
|
||
partner.inn, partner.director_name, partner.phone, partner.email,
|
||
partner.rating, partner.sales_locations, partner_id
|
||
))
|
||
return {"message": "Partner updated successfully"}
|
||
except Exception as e:
|
||
if "duplicate key value violates unique constraint" in str(e):
|
||
raise HTTPException(status_code=400, detail="Partner with this INN already exists")
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.delete("/{partner_id}")
|
||
async def delete_partner(partner_id: int):
|
||
"""Удаление партнера"""
|
||
try:
|
||
db.execute_query(
|
||
"DELETE FROM partners WHERE partner_id = %s",
|
||
(partner_id,)
|
||
)
|
||
return {"message": "Partner deleted successfully"}
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.get("/{partner_id}/discount", response_model=DiscountResponse)
|
||
async def calculate_partner_discount(partner_id: int):
|
||
"""
|
||
Расчет скидки для партнера на основе общего количества продаж
|
||
Соответствует модулю 2 ТЗ
|
||
"""
|
||
try:
|
||
# Получаем общее количество продаж партнера
|
||
result = db.execute_query("""
|
||
SELECT COALESCE(SUM(quantity), 0) as total_sales
|
||
FROM sales WHERE partner_id = %s
|
||
""", (partner_id,))
|
||
|
||
total_sales = result[0]["total_sales"] if result else Decimal('0')
|
||
|
||
# Расчет скидки согласно бизнес-правилам ТЗ
|
||
if total_sales < 10000:
|
||
discount = 0
|
||
elif total_sales < 50000:
|
||
discount = 5
|
||
elif total_sales < 300000:
|
||
discount = 10
|
||
else:
|
||
discount = 15
|
||
|
||
return DiscountResponse(
|
||
partner_id=partner_id,
|
||
total_sales=total_sales,
|
||
discount_percent=discount
|
||
)
|
||
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|