"""Notify pusat about cycle close request / cancel.""" from __future__ import annotations import logging from typing import Any import httpx from django.conf import settings from apps.farms.models import Cycle logger = logging.getLogger(__name__) class PusatCloseError(Exception): def __init__(self, message: str): self.message = message super().__init__(message) def _active_site_id_for_cycle(cycle: Cycle) -> int | None: site = cycle.kandang.site if site.pusat_active_site_id is not None: return int(site.pusat_active_site_id) return None def _configured(active_site_id: int | None) -> bool: return bool(settings.PUSAT_BASE_URL and settings.PUSAT_API_KEY and active_site_id) def notify_pusat_close_request(cycle: Cycle, *, cancelled: bool = False) -> None: """POST ingest/cancel to pusat. Raises PusatCloseError on failure when configured.""" active_site_id = _active_site_id_for_cycle(cycle) if not _configured(active_site_id): logger.info("Pusat close channel not configured; skipping notify for cycle %s", cycle.pk) return base = settings.PUSAT_BASE_URL.rstrip("/") headers = {"X-API-Key": settings.PUSAT_API_KEY, "Content-Type": "application/json"} try: if cancelled: url = f"{base}/cycle-close/cancel/" payload: dict[str, Any] = { "active_site_id": active_site_id, "source_cycle_id": cycle.pk, } else: url = f"{base}/cycle-close/ingest/" payload = { "active_site_id": active_site_id, "source_cycle_id": cycle.pk, "kandang_name": cycle.kandang.kandang_name, "site_name": cycle.kandang.site.site_name, "start_date": cycle.start_date.isoformat(), "proposed_end_date": cycle.proposed_end_date.isoformat() if cycle.proposed_end_date else None, "doc_in_weight": cycle.doc_in_weight, "doc_in_count": cycle.doc_in_count, "total_days": cycle.total_days, "requested_at": cycle.close_requested_at.isoformat() if cycle.close_requested_at else None, } with httpx.Client(timeout=30) as client: response = client.post(url, json=payload, headers=headers) if response.status_code >= 400: detail = response.text[:300] raise PusatCloseError(f"gagal kirim ke pusat — coba lagi ({response.status_code}: {detail})") except PusatCloseError: raise except httpx.HTTPError as exc: logger.exception("Pusat notify failed for cycle %s", cycle.pk) raise PusatCloseError("gagal kirim ke pusat — coba lagi") from exc