from django.db import migrations def merge_unit(apps, legacy_slug, canonical_slug, canonical_name, canonical_description): Unit = apps.get_model("staff", "OrganizationalUnit") Membership = apps.get_model("staff", "UnitMembership") StaffProfile = apps.get_model("staff", "StaffProfile") TicketCategory = apps.get_model("tickets", "TicketCategory") Ticket = apps.get_model("tickets", "Ticket") GroupDispatch = apps.get_model("tickets", "GroupDispatch") ContactGroup = apps.get_model("customers", "ContactGroup") CustomerProfile = apps.get_model("customers", "CustomerProfile") SMSTemplate = apps.get_model("notifications", "SMSTemplate") TicketMagicLink = apps.get_model("accounts", "TicketMagicLink") legacy = Unit.objects.filter(slug=legacy_slug).first() canonical = Unit.objects.filter(slug=canonical_slug).first() if legacy is None: return if canonical is None: legacy.slug = canonical_slug legacy.name = canonical_name legacy.description = canonical_description legacy.is_active = True legacy.accepts_external_tickets = True legacy.show_in_customer_form = True legacy.save() return canonical.permissions.add(*legacy.permissions.all()) TicketCategory.objects.filter(unit=legacy).update(unit=canonical) Ticket.objects.filter(owning_unit=legacy).update(owning_unit=canonical) Ticket.objects.filter(assigned_unit=legacy).update(assigned_unit=canonical) GroupDispatch.objects.filter(unit=legacy).update(unit=canonical) TicketMagicLink.objects.filter(created_unit=legacy).update(created_unit=canonical) StaffProfile.objects.filter(primary_unit=legacy).update(primary_unit=canonical) for membership in Membership.objects.filter(unit=legacy): existing = Membership.objects.filter(user_id=membership.user_id, unit=canonical).first() if existing is None: membership.unit = canonical membership.save(update_fields=["unit", "updated_at"]) continue existing.permissions.add(*membership.permissions.all()) existing.is_active = existing.is_active or membership.is_active existing.is_primary = existing.is_primary or membership.is_primary if membership.ticket_scope == "UNIT": existing.ticket_scope = "UNIT" existing.save(update_fields=["is_active", "is_primary", "ticket_scope", "updated_at"]) membership.delete() for group in ContactGroup.objects.filter(unit=legacy): existing = ContactGroup.objects.filter(unit=canonical, name=group.name).first() if existing is None: group.unit = canonical group.save(update_fields=["unit", "updated_at"]) continue for profile in CustomerProfile.objects.filter(groups=group): profile.groups.add(existing) GroupDispatch.objects.filter(contact_group=group).update(contact_group=existing) group.delete() for template in SMSTemplate.objects.filter(unit=legacy): if SMSTemplate.objects.filter(unit=canonical, event_type=template.event_type).exists(): template.delete() else: template.unit = canonical template.save(update_fields=["unit", "updated_at"]) legacy.delete() def merge_legacy_warehouse_units(apps, schema_editor): merge_unit(apps, "logistics", "warehouse-loading", "بارگیری انبار", "بارگیری، انبار و ارسال") merge_unit(apps, "warehouse", "warehouse-loading", "بارگیری انبار", "بارگیری، انبار و ارسال") class Migration(migrations.Migration): dependencies = [("tickets", "0013_merge_legacy_accounting_unit")] operations = [migrations.RunPython(merge_legacy_warehouse_units, migrations.RunPython.noop)]