add chicken counting, mortality api for daily data sync. Also adjust karung sync to sync every 30 sec after publish cutoff time to update real data without clicking sync button manually
This commit is contained in:
1 parent
5ae477a99d
commit
6c21af745d
17 files changed
+791
-119
No files matched your search
@@ -28,6 +28,10 @@ from apps.operations.serializers import (
|
||||
ManualInputSerializer,
|
||||
)
|
||||
from apps.operations.services.karung_web import KarungWebError, sync_karung_for_cycle
|
||||
from apps.operations.services.chicken_counting_edge import (
|
||||
ChickenCountingEdgeError,
|
||||
sync_chicken_counting_for_cycle,
|
||||
)
|
||||
from apps.operations.services.visibility import dashboard_publish_time, visible_through_date
|
||||
|
||||
READ_ACTIONS = frozenset({"list", "retrieve", "latest_average", "latest", "dates"})
|
||||
@@ -70,14 +74,51 @@ class ManualInputViewSet(CycleScopedViewSet):
|
||||
|
||||
|
||||
class ChickenCountingViewSet(CycleScopedViewSet):
|
||||
"""Chicken counting + mortality IoT — not subject to dashboard publish cutoff."""
|
||||
|
||||
queryset = ChickenCounting.objects.select_related("cycle").all()
|
||||
serializer_class = ChickenCountingSerializer
|
||||
|
||||
def applies_visibility_filter(self) -> bool:
|
||||
return False
|
||||
|
||||
@action(detail=False, methods=["post"], url_path="sync")
|
||||
def sync_from_edge(self, request):
|
||||
cycle_id = request.data.get("cycle_id")
|
||||
if not cycle_id:
|
||||
return Response(
|
||||
{"detail": "cycle_id is required."},
|
||||
status=status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
try:
|
||||
cycle = Cycle.objects.select_related("kandang").get(pk=cycle_id)
|
||||
except Cycle.DoesNotExist:
|
||||
return Response({"detail": "Cycle not found."}, status=status.HTTP_404_NOT_FOUND)
|
||||
try:
|
||||
summary = sync_chicken_counting_for_cycle(cycle)
|
||||
except (ChickenCountingEdgeError, ValidationError) as exc:
|
||||
code = getattr(exc, "status_code", None)
|
||||
return Response(
|
||||
{"detail": str(exc)},
|
||||
status=code if code and code >= 400 else status.HTTP_502_BAD_GATEWAY,
|
||||
)
|
||||
return Response(
|
||||
{
|
||||
"upserted": summary["upserted"],
|
||||
"dates": [d.isoformat() for d in summary["dates"]],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class ChickenWeightViewSet(CycleScopedViewSet):
|
||||
"""Chicken weight — not subject to dashboard publish cutoff."""
|
||||
|
||||
queryset = ChickenWeight.objects.select_related("cycle").all()
|
||||
serializer_class = ChickenWeightSerializer
|
||||
|
||||
def applies_visibility_filter(self) -> bool:
|
||||
return False
|
||||
|
||||
@action(detail=False, methods=["get"], url_path="latest-avg")
|
||||
def latest_average(self, request):
|
||||
cycle_id = request.query_params.get("cycle_id")
|
||||
|
||||
Reference in new issue
Block a user