update link registration site to executive dashboard

This commit is contained in:
Alberto-Audrix committed 2026-09-15 09:44:45 +07:00
1 parent 1e6f6b3b57
commit d0d1ae7d24
26 files changed
+1044 -55

No files matched your search

@@ -0,0 +1,36 @@
# Generated manually for PusatRegistration
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("farms", "0015_cycle_close_request"),
]
operations = [
migrations.CreateModel(
name="PusatRegistration",
fields=[
("registration_id", models.BigAutoField(primary_key=True, serialize=False)),
("code", models.SlugField(max_length=64)),
("active_site_id", models.BigIntegerField()),
("registered_at", models.DateTimeField(auto_now=True)),
("created_at", models.DateTimeField(auto_now_add=True)),
(
"site",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="pusat_registration",
to="farms.site",
),
),
],
options={
"db_table": "pusat_registrations",
"ordering": ["-registered_at"],
},
),
]
@@ -0,0 +1,121 @@
# Convert Site.site_id from BigAutoField to name-based SlugField PK with numeric suffix.
# atomic=False: PostgreSQL cannot ALTER TABLE in the same transaction after PK UPDATEs.
from django.db import migrations, models
import django.db.models.deletion
from django.utils.text import slugify
def _unique_slug(site_name: str, old_pk: str, used: set[str]) -> str:
base = slugify(str(site_name or "").strip())[:55] or f"site-{old_pk}"[:55]
try:
seed = int(old_pk) % 10000
except ValueError:
seed = sum(ord(c) for c in old_pk) % 10000
for i in range(10000):
code = f"{base}-{(seed + i) % 10000:04d}"
if code not in used:
used.add(code)
return code
raise RuntimeError(f"Could not allocate site id for {old_pk}")
def forwards_slug_pks(apps, schema_editor):
Site = apps.get_model("farms", "Site")
Kandang = apps.get_model("farms", "Kandang")
PusatRegistration = apps.get_model("farms", "PusatRegistration")
used: set[str] = set()
mapping: dict[str, str] = {}
for site in Site.objects.all().order_by("site_id"):
old = str(site.site_id)
mapping[old] = _unique_slug(site.site_name, old, used)
for old_id, new_id in mapping.items():
if old_id == new_id:
continue
Kandang.objects.filter(site_id=old_id).update(site_id=new_id)
PusatRegistration.objects.filter(site_id=old_id).update(site_id=new_id)
Site.objects.filter(site_id=old_id).update(site_id=new_id)
# Ensure site names are unique before adding the constraint.
seen_names: dict[str, int] = {}
for site in Site.objects.all().order_by("site_id"):
name = site.site_name
count = seen_names.get(name, 0)
seen_names[name] = count + 1
if count == 0:
continue
suffix = f"-{count + 1}"
site.site_name = f"{name[: 30 - len(suffix)]}{suffix}"
site.save(update_fields=["site_name"])
def noop_reverse(apps, schema_editor):
raise RuntimeError("Cannot reverse site_id slug migration.")
class Migration(migrations.Migration):
atomic = False
dependencies = [
("farms", "0016_pusat_registration"),
]
operations = [
migrations.AlterField(
model_name="kandang",
name="site",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.CASCADE,
related_name="kandangs",
to="farms.site",
),
),
migrations.AlterField(
model_name="pusatregistration",
name="site",
field=models.OneToOneField(
db_constraint=False,
on_delete=django.db.models.deletion.CASCADE,
related_name="pusat_registration",
to="farms.site",
),
),
migrations.AlterField(
model_name="site",
name="site_id",
field=models.CharField(max_length=64, primary_key=True, serialize=False),
),
migrations.RunPython(forwards_slug_pks, noop_reverse),
migrations.AlterField(
model_name="site",
name="site_id",
field=models.SlugField(max_length=64, primary_key=True, serialize=False),
),
migrations.AlterField(
model_name="site",
name="site_name",
field=models.CharField(max_length=30, unique=True),
),
migrations.AlterField(
model_name="kandang",
name="site",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="kandangs",
to="farms.site",
),
),
migrations.AlterField(
model_name="pusatregistration",
name="site",
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="pusat_registration",
to="farms.site",
),
),
]
@@ -0,0 +1,93 @@
# Append a 4-digit suffix to site ids that are still name-only slugs.
import re
import secrets
from django.db import migrations, models
import django.db.models.deletion
from django.utils.text import slugify
_HAS_SUFFIX = re.compile(r"-\d{4}$")
def forwards_add_numeric_suffix(apps, schema_editor):
Site = apps.get_model("farms", "Site")
Kandang = apps.get_model("farms", "Kandang")
PusatRegistration = apps.get_model("farms", "PusatRegistration")
used = set(Site.objects.values_list("site_id", flat=True))
mapping: dict[str, str] = {}
for site in Site.objects.all().order_by("site_id"):
old = str(site.site_id)
if _HAS_SUFFIX.search(old):
continue
base = slugify(str(site.site_name or "").strip())[:55] or old[:55]
for _ in range(32):
candidate = f"{base}-{secrets.randbelow(10_000):04d}"
if candidate not in used:
used.add(candidate)
mapping[old] = candidate
break
else:
raise RuntimeError(f"Could not allocate numeric site id for {old}")
for old_id, new_id in mapping.items():
Kandang.objects.filter(site_id=old_id).update(site_id=new_id)
PusatRegistration.objects.filter(site_id=old_id).update(site_id=new_id)
Site.objects.filter(site_id=old_id).update(site_id=new_id)
def noop_reverse(apps, schema_editor):
raise RuntimeError("Cannot reverse site id numeric suffix migration.")
class Migration(migrations.Migration):
atomic = False
dependencies = [
("farms", "0017_site_slug_pk"),
]
operations = [
migrations.AlterField(
model_name="kandang",
name="site",
field=models.ForeignKey(
db_constraint=False,
on_delete=django.db.models.deletion.CASCADE,
related_name="kandangs",
to="farms.site",
),
),
migrations.AlterField(
model_name="pusatregistration",
name="site",
field=models.OneToOneField(
db_constraint=False,
on_delete=django.db.models.deletion.CASCADE,
related_name="pusat_registration",
to="farms.site",
),
),
migrations.RunPython(forwards_add_numeric_suffix, noop_reverse),
migrations.AlterField(
model_name="kandang",
name="site",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="kandangs",
to="farms.site",
),
),
migrations.AlterField(
model_name="pusatregistration",
name="site",
field=models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="pusat_registration",
to="farms.site",
),
),
]
@@ -0,0 +1,52 @@
# Move pusat registration fields onto sites; drop pusat_registrations.
from django.db import migrations, models
def forwards_copy_registrations(apps, schema_editor):
Site = apps.get_model("farms", "Site")
PusatRegistration = apps.get_model("farms", "PusatRegistration")
for row in PusatRegistration.objects.select_related("site").all():
site = row.site
site.pusat_code = row.code or ""
site.pusat_active_site_id = row.active_site_id
site.pusat_registered_at = row.registered_at
site.save(
update_fields=[
"pusat_code",
"pusat_active_site_id",
"pusat_registered_at",
"updated_at",
]
)
def noop_reverse(apps, schema_editor):
raise RuntimeError("Cannot reverse pusat fields onto sites.")
class Migration(migrations.Migration):
dependencies = [
("farms", "0018_site_id_numeric_suffix"),
]
operations = [
migrations.AddField(
model_name="site",
name="pusat_code",
field=models.SlugField(blank=True, default="", max_length=64),
),
migrations.AddField(
model_name="site",
name="pusat_active_site_id",
field=models.BigIntegerField(blank=True, null=True),
),
migrations.AddField(
model_name="site",
name="pusat_registered_at",
field=models.DateTimeField(blank=True, null=True),
),
migrations.RunPython(forwards_copy_registrations, noop_reverse),
migrations.DeleteModel(name="PusatRegistration"),
]