Files
dashboard-cpsp/backend/apps/farms/services/pusat_close.py
T

79 lines
2.8 KiB
Python

"""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