import logging from fastapi import APIRouter, Depends, HTTPException, status from app.core.config import settings from app.repositories.pricing import find_effective_price_rule from app.repositories.scheme_seats import get_scheme_version_seat_by_seat_id from app.repositories.scheme_versions import get_current_scheme_version from app.repositories.schemes import get_scheme_record_by_scheme_id from app.schemas.test_mode import TestSeatPreviewResponse from app.security.auth import require_api_key router = APIRouter() logger = logging.getLogger(__name__) @router.get(f"{settings.api_v1_prefix}/schemes/{{scheme_id}}/test/seats/{{seat_id}}", response_model=TestSeatPreviewResponse) async def preview_test_seat( scheme_id: str, seat_id: str, role: str = Depends(require_api_key), ): scheme = await get_scheme_record_by_scheme_id(scheme_id) version = await get_current_scheme_version( scheme_id=scheme.scheme_id, current_version_number=scheme.current_version_number, ) seat = await get_scheme_version_seat_by_seat_id( scheme_version_id=version.scheme_version_id, seat_id=seat_id, ) matched_rule_level = None matched_target_ref = None pricing_category_id = None amount = None currency = None has_price = False if not seat.seat_id: return TestSeatPreviewResponse( scheme_id=scheme.scheme_id, scheme_version_id=version.scheme_version_id, seat_id=seat.seat_id, element_id=seat.element_id, sector_id=seat.sector_id, group_id=seat.group_id, row_label=seat.row_label, seat_number=seat.seat_number, selectable=False, has_price=False, matched_rule_level=None, matched_target_ref=None, pricing_category_id=None, amount=None, currency=None, reason_code="missing_seat_id", reason_message="Seat is not sellable because seat_id is missing.", ) try: matched_rule_level, rule = await find_effective_price_rule( scheme_id=scheme.scheme_id, seat_id=seat.seat_id, group_id=seat.group_id, sector_id=seat.sector_id, ) matched_target_ref = rule["target_ref"] pricing_category_id = rule["pricing_category_id"] amount = str(rule["amount"]) currency = rule["currency"] has_price = True except HTTPException as exc: if exc.status_code != status.HTTP_404_NOT_FOUND: raise except Exception as exc: logger.exception( "preview_test_seat failed for scheme_id=%s seat_id=%s", scheme_id, seat_id, ) raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail={ "code": "test_preview_failed", "message": f"Не удалось построить preview: {exc.__class__.__name__}: {exc}", }, ) if has_price: reason_code = "ok" reason_message = "Seat is sellable." else: reason_code = "no_price_rule" reason_message = "Seat is not sellable because no effective price rule was found." return TestSeatPreviewResponse( scheme_id=scheme.scheme_id, scheme_version_id=version.scheme_version_id, seat_id=seat.seat_id, element_id=seat.element_id, sector_id=seat.seat_id and seat.sector_id, group_id=seat.group_id, row_label=seat.row_label, seat_number=seat.seat_number, selectable=has_price, has_price=has_price, matched_rule_level=matched_rule_level, matched_target_ref=matched_target_ref, pricing_category_id=pricing_category_id, amount=amount, currency=currency, reason_code=reason_code, reason_message=reason_message, )