98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""
|
|
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.")
|
|
)
|