"""Push close decisions from pusat to farm-location dashboard-cpsp.""" from __future__ import annotations import logging import httpx from apps.farms.models import Cycle logger = logging.getLogger(__name__) class SiteClosePushError(Exception): def __init__(self, message: str): self.message = message super().__init__(message) def push_close_decision(cycle: Cycle, *, approved: bool) -> None: active_site = cycle.active_site if ( not active_site or not active_site.api_base_url or not active_site.api_key or not cycle.source_cycle_id ): logger.info("No active-site channel configured for cycle %s; skip push", cycle.pk) return base = active_site.api_base_url.rstrip("/") url = f"{base}/cycles/{cycle.source_cycle_id}/apply-close-decision/" payload = {"decision": "approve" if approved else "reject"} if approved: if not cycle.end_date: raise SiteClosePushError("Approved cycle is missing end_date.") payload["end_date"] = cycle.end_date.isoformat() try: response = httpx.post( url, json=payload, headers={ "X-API-Key": active_site.api_key, "Content-Type": "application/json", }, timeout=30.0, ) if response.status_code >= 400: raise SiteClosePushError( f"Gagal kirim keputusan ke situs ({response.status_code}: {response.text[:200]})" ) except SiteClosePushError: raise except httpx.HTTPError as exc: logger.exception("Push close decision failed for cycle %s", cycle.pk) raise SiteClosePushError("Gagal kirim keputusan ke situs — coba lagi") from exc