loko/streetup/contracts/management/commands/create_monthly_orders_2026.py
2026-07-22 14:48:40 +02:00

180 lines
6.8 KiB
Python

"""
Commande Django pour créer les commandes mensuelles 2026.
Pour chaque mois de mars à décembre 2026, crée 3 commandes dans un contrat donné :
- Appels <Mois> 2026
- Réparations <Mois> 2026
- Préventif <Mois> 2026
Vérifie l'existence avant d'insérer (idempotent).
Usage :
python manage.py create_monthly_orders_2026 --contract <contract_number>
python manage.py create_monthly_orders_2026 --contract <contract_number> --dry-run
"""
from django.core.management.base import BaseCommand, CommandError
from django.utils.translation import override as translation_override
from datetime import date
from contracts.models import Contract, ContractOrder
# ---------------------------------------------------------------------------
# Données de référence
# ---------------------------------------------------------------------------
MONTHS = [
# (numéro, nom_affichage, préposition)
(3, "Mars", "de mars"),
(4, "Avril", "d'avril"),
(5, "Mai", "de mai"),
(6, "Juin", "de juin"),
(7, "Juillet", "de juillet"),
(8, "Août", "d'août"),
(9, "Septembre", "de septembre"),
(10, "Octobre", "d'octobre"),
(11, "Novembre", "de novembre"),
(12, "Décembre", "de décembre"),
]
YEAR = 2026
# Modèle de commande : (suffixe_code, gabarit_description)
ORDER_TEMPLATES = [
("Appels", "Appels du mois {prep} {year}"),
("Réparations", "Réparations du mois {prep} {year}"),
("Préventif", "Interventions préventives du mois {prep} {year}"),
]
# ---------------------------------------------------------------------------
# Commande
# ---------------------------------------------------------------------------
class Command(BaseCommand):
help = (
"Crée les 3 commandes mensuelles (Appels / Réparations / Préventif) "
"pour chaque mois de mars à décembre 2026 dans le contrat spécifié."
)
def add_arguments(self, parser):
parser.add_argument(
"--contract",
required=True,
metavar="CONTRACT_NUMBER",
help="Numéro du contrat cible (ex: 2024-MAINT-001).",
)
parser.add_argument(
"--dry-run",
action="store_true",
default=False,
help="Simule sans écrire en base de données.",
)
parser.add_argument(
"--status",
default="pending",
metavar="STATUS",
help=(
"Statut des commandes créées. "
"Valeurs possibles : pending, sent, completed, invoiced, paid, cancelled. "
"(défaut : pending)"
),
)
def handle(self, *args, **options):
contract_number = options["contract"]
dry_run = options["dry_run"]
status = options["status"]
# Forcer le français pour les éventuelles traductions Django
with translation_override("fr"):
try:
contract = Contract.objects.get(contract_number=contract_number)
except Contract.DoesNotExist:
# Afficher les contrats disponibles pour aider l'utilisateur
available = list(
Contract.objects.values_list("contract_number", flat=True).order_by("contract_number")
)
raise CommandError(
f"Contrat « {contract_number} » introuvable.\n"
f"Contrats disponibles : {', '.join(available) if available else '(aucun)'}"
)
self.stdout.write(
self.style.SUCCESS(f"\nContrat trouvé : {contract}\n")
)
if dry_run:
self.stdout.write(self.style.WARNING("⚠ Mode simulation (--dry-run) : aucune donnée ne sera écrite.\n"))
created_count = 0
skipped_count = 0
for month_num, month_name, month_prep in MONTHS:
# Dates : 1er du mois → 1er du mois suivant (ou 1er janvier 2027 pour décembre)
order_date = date(YEAR, month_num, 1)
if month_num == 12:
delivery_date = date(YEAR + 1, 1, 1)
else:
delivery_date = date(YEAR, month_num + 1, 1)
self.stdout.write(f"\n--- {month_name} {YEAR} ---")
for prefix, desc_template in ORDER_TEMPLATES:
order_code = f"{prefix} {month_name} {YEAR}"
description = desc_template.format(prep=month_prep, year=YEAR)
# Vérification de l'existence (case-insensitive sur order_code)
existing = ContractOrder.objects.filter(
contract=contract,
order_code__iexact=order_code,
).first()
if existing:
self.stdout.write(
self.style.WARNING(
f" ⏭ EXISTANT — {existing.order_code!r} (id={existing.pk})"
)
)
skipped_count += 1
else:
if dry_run:
self.stdout.write(
self.style.SUCCESS(
f" ✔ À CRÉER — code={order_code!r} | desc={description!r}"
f" | commande={order_date} | livraison={delivery_date}"
)
)
else:
obj = ContractOrder.objects.create(
contract=contract,
order_code=order_code,
description=description,
order_date=order_date,
delivery_date=delivery_date,
order_status=status,
)
self.stdout.write(
self.style.SUCCESS(
f" ✔ CRÉÉ — {obj.order_code!r} (id={obj.pk})"
)
)
created_count += 1
# Résumé
self.stdout.write("\n" + "=" * 60)
if dry_run:
self.stdout.write(
self.style.WARNING(
f"Simulation terminée : {created_count} commande(s) à créer, "
f"{skipped_count} déjà existante(s)."
)
)
else:
self.stdout.write(
self.style.SUCCESS(
f"Terminé : {created_count} commande(s) créée(s), "
f"{skipped_count} déjà existante(s) (ignorée(s))."
)
)