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

113 lines
3.6 KiB
Python

"""Link HQ Site rows to ActiveSite registry entries (Pengaturan view list)."""
from __future__ import annotations
from django.db import transaction
from django.utils.text import slugify
from apps.farms.models import Kandang, Site
from apps.sync.models import ActiveSite
def desired_hq_site_id(active_site: ActiveSite) -> str:
"""HQ Site PK should match the farm site slug when known."""
source = str(active_site.source_site_id or "").strip()
if source:
return source[:64]
code = slugify(str(active_site.code or "").strip())[:64]
if code:
return code
raise ValueError("ActiveSite needs source_site_id or code to create an HQ site.")
@transaction.atomic
def ensure_hq_site_for_active_site(active_site: ActiveSite) -> Site:
"""
Ensure the active-site registry entry has an HQ Site for farm visibility.
Site.site_id matches ActiveSite.source_site_id (farm Site.site_id) when set.
Prefers an existing linked site, then a site already keyed by that id, then an
unlinked site owned by the registrar with a matching name (re-keyed if needed),
otherwise creates a new Site.
"""
owner = active_site.managed_by
if owner is None:
raise ValueError("ActiveSite.managed_by is required to create an HQ site.")
desired_id = desired_hq_site_id(active_site)
site_name = (active_site.name or active_site.code or "Site")[:30]
existing = Site.objects.filter(active_site=active_site).first()
if existing is not None:
if existing.pk == desired_id:
return existing
return _rekey_site(existing, desired_id=desired_id, site_name=site_name, owner=owner)
by_pk = Site.objects.filter(pk=desired_id).first()
if by_pk is not None:
by_pk.active_site = active_site
by_pk.user = owner
if by_pk.site_name != site_name:
by_pk.site_name = site_name
by_pk.save(update_fields=["active_site", "user", "site_name", "updated_at"])
return by_pk
orphan = (
Site.objects.filter(
user=owner, active_site__isnull=True, site_name__iexact=site_name
)
.order_by("pk")
.first()
)
if orphan is None and active_site.code:
orphan = (
Site.objects.filter(
user=owner, active_site__isnull=True, site_name__iexact=active_site.code
)
.order_by("pk")
.first()
)
if orphan is not None:
if orphan.pk == desired_id:
orphan.active_site = active_site
orphan.save(update_fields=["active_site", "updated_at"])
return orphan
return _rekey_site(
orphan,
desired_id=desired_id,
site_name=site_name,
owner=owner,
active_site=active_site,
)
return Site.objects.create(
site_id=desired_id,
site_name=site_name,
user=owner,
active_site=active_site,
)
def _rekey_site(
old: Site,
*,
desired_id: str,
site_name: str,
owner,
active_site: ActiveSite | None = None,
) -> Site:
"""Move an HQ site (and its kandangs) onto the farm slug primary key."""
link = active_site if active_site is not None else old.active_site
new_site = Site.objects.create(
site_id=desired_id,
site_name=site_name or old.site_name,
user=owner,
active_site=None,
)
Kandang.objects.filter(site=old).update(site=new_site)
old_active = old.active_site
old.delete()
new_site.active_site = link or old_active
new_site.save(update_fields=["active_site", "updated_at"])
return new_site