113 lines
3.6 KiB
Python
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
|