""" Management command to invert the vertical_order of SignPanels for a given organization. For each pole, the vertical_order values are reversed: if orders on a pole are [1, 2, 3], they become [3, 2, 1] formula: new_order = max_order + min_order - old_order Usage: python manage.py invert_vertical_order --org_id 1 [--dry-run] """ from django.core.management.base import BaseCommand from django.db import transaction from sign.models import SignPanel, SignPole class Command(BaseCommand): help = "Inverse l'ordre vertical des panneaux par poteau pour une organisation donnée." def add_arguments(self, parser): parser.add_argument( "--org_id", type=int, default=1, help="ID de l'organisation (défaut: 1)", ) parser.add_argument( "--dry-run", action="store_true", help="Affiche les modifications sans les appliquer", ) def handle(self, *args, **options): org_id = options["org_id"] dry_run = options["dry_run"] if dry_run: self.stdout.write(self.style.WARNING("Mode DRY-RUN: aucune modification ne sera enregistrée.\n")) # Get all distinct pole IDs that have panels for this organisation pole_ids = ( SignPanel.objects .filter(organization_id=org_id, pole__isnull=False, vertical_order__isnull=False) .values_list("pole_id", flat=True) .distinct() ) pole_ids = list(pole_ids) self.stdout.write(f"Organisation {org_id}: {len(pole_ids)} poteau(x) concerné(s).\n") total_panels_updated = 0 with transaction.atomic(): for pole_id in pole_ids: panels = list( SignPanel.objects .filter(organization_id=org_id, pole_id=pole_id, vertical_order__isnull=False) .order_by("vertical_order") ) if not panels: continue orders = [p.vertical_order for p in panels] min_order = min(orders) max_order = max(orders) if min_order == max_order: # Only one distinct value, nothing to invert continue self.stdout.write(f" Poteau {pole_id}: orders {orders} -> ", ending="") updates = [] for panel in panels: new_order = max_order + min_order - panel.vertical_order updates.append((panel, new_order)) new_orders = [o for _, o in updates] self.stdout.write(str(new_orders)) if not dry_run: for panel, new_order in updates: panel.vertical_order = new_order panel.save(update_fields=["vertical_order"]) total_panels_updated += 1 if dry_run: # Rollback even if somehow something was written transaction.set_rollback(True) if dry_run: self.stdout.write(self.style.WARNING("\nDRY-RUN terminé, aucune modification enregistrée.")) else: self.stdout.write( self.style.SUCCESS(f"\n{total_panels_updated} panneau(x) mis à jour avec succès.") )