master-floor/ressult/app/routes/partners.py
2025-11-26 19:31:33 +03:00

157 lines
6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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