from __future__ import annotations from app.core.config import settings from app.repositories.scheme_seats import list_scheme_version_seats from app.repositories.scheme_version_pricing import ( find_effective_snapshot_price_rule, list_scheme_version_snapshot_categories, list_scheme_version_snapshot_rules, ) from app.services.scheme_validation import build_scheme_validation_report async def _build_snapshot_pricing_coverage(*, scheme_version_id: str) -> dict: seats = await list_scheme_version_seats(scheme_version_id) snapshot_categories = await list_scheme_version_snapshot_categories(scheme_version_id) snapshot_rules = await list_scheme_version_snapshot_rules(scheme_version_id) snapshot_available = len(snapshot_categories) > 0 or len(snapshot_rules) > 0 priced_seats = 0 unpriced_seats = 0 for seat in seats: if not seat.seat_id: unpriced_seats += 1 continue if not snapshot_available: unpriced_seats += 1 continue try: await find_effective_snapshot_price_rule( scheme_version_id=scheme_version_id, seat_id=seat.seat_id, group_id=seat.group_id, sector_id=seat.sector_id, ) priced_seats += 1 except Exception: unpriced_seats += 1 total_seats = len(seats) coverage_percent = round((priced_seats / total_seats) * 100, 2) if total_seats > 0 else 100.0 return { "snapshot": { "available": snapshot_available, "categories_count": len(snapshot_categories), "rules_count": len(snapshot_rules), }, "pricing_coverage": { "total_seats": total_seats, "priced_seats": priced_seats, "unpriced_seats": unpriced_seats, "coverage_percent": coverage_percent, }, } async def build_publish_readiness( *, scheme_id: str, scheme_version_id: str, status: str, ) -> dict: validation = await build_scheme_validation_report( scheme_id=scheme_id, scheme_version_id=scheme_version_id, ) snapshot_state = await _build_snapshot_pricing_coverage( scheme_version_id=scheme_version_id, ) validation_publishable = bool(validation["summary"]["is_publishable"]) snapshot_available = bool(snapshot_state["snapshot"]["available"]) full_pricing_coverage = snapshot_state["pricing_coverage"]["unpriced_seats"] == 0 require_full_pricing_coverage = bool(settings.publish_require_full_pricing_coverage) pricing_gate_passed = snapshot_available and ( full_pricing_coverage if require_full_pricing_coverage else True ) is_ready_to_publish = validation_publishable and pricing_gate_passed return { "scheme_id": scheme_id, "scheme_version_id": scheme_version_id, "status": status, "validation_summary": validation["summary"], "pricing_coverage": snapshot_state["pricing_coverage"], "snapshot": snapshot_state["snapshot"], "readiness": { "validation_publishable": validation_publishable, "snapshot_available": snapshot_available, "require_full_pricing_coverage": require_full_pricing_coverage, "full_pricing_coverage": full_pricing_coverage, "pricing_gate_passed": pricing_gate_passed, "is_ready_to_publish": is_ready_to_publish, }, }