haikal/inventory/management/commands/analyze_car_hierarchy.py
2025-06-22 13:25:54 +03:00

179 lines
7.4 KiB
Python

from django.core.management.base import BaseCommand
from django.db.models import Count
from inventory.models import CarMake, CarModel, CarSerie, CarTrim
import csv
import os
from django.conf import settings
class Command(BaseCommand):
help = "Analyzes the car hierarchy to identify makes without models, models without series, and series without trims"
def add_arguments(self, parser):
parser.add_argument(
"--export",
action="store_true",
help="Export results to CSV files",
)
parser.add_argument(
"--export-path",
type=str,
default="exports",
help='Directory to export CSV files (default: "exports")',
)
def handle(self, *args, **options):
export = options["export"]
export_path = options["export_path"]
# Create export directory if needed
if export:
export_dir = os.path.join(settings.BASE_DIR, export_path)
if not os.path.exists(export_dir):
os.makedirs(export_dir)
# Analyze makes without models
all_makes = CarMake.objects.all()
total_makes = all_makes.count()
makes_without_models = CarMake.objects.annotate(
model_count=Count("carmodel")
).filter(model_count=0)
makes_without_models_count = makes_without_models.count()
self.stdout.write(self.style.SUCCESS(f"Total car makes: {total_makes}"))
self.stdout.write(
self.style.SUCCESS(
f"Car makes without models: {makes_without_models_count} "
f"({makes_without_models_count / total_makes * 100:.2f}% of all makes)"
)
)
if makes_without_models_count > 0:
self.stdout.write("\nSample of car makes without models:")
for make in makes_without_models[:5]:
self.stdout.write(f"- {make.name}")
# Analyze models without series
all_models = CarModel.objects.all()
total_models = all_models.count()
models_without_series = CarModel.objects.annotate(
serie_count=Count("carserie")
).filter(serie_count=0)
models_without_series_count = models_without_series.count()
self.stdout.write(self.style.SUCCESS(f"\nTotal car models: {total_models}"))
self.stdout.write(
self.style.SUCCESS(
f"Car models without series: {models_without_series_count} "
f"({models_without_series_count / total_models * 100:.2f}% of all models)"
)
)
if models_without_series_count > 0:
self.stdout.write("\nSample of car models without series:")
for model in models_without_series[:5]:
self.stdout.write(f"- {model.name} (Make: {model.id_car_make.name})")
# Analyze series without trims
all_series = CarSerie.objects.all()
total_series = all_series.count()
series_without_trims = CarSerie.objects.annotate(
trim_count=Count("cartrim")
).filter(trim_count=0)
series_without_trims_count = series_without_trims.count()
self.stdout.write(self.style.SUCCESS(f"\nTotal car series: {total_series}"))
self.stdout.write(
self.style.SUCCESS(
f"Car series without trims: {series_without_trims_count} "
f"({series_without_trims_count / total_series * 100:.2f}% of all series)"
)
)
if series_without_trims_count > 0:
self.stdout.write("\nSample of car series without trims:")
for serie in series_without_trims[:5]:
self.stdout.write(
f"- {serie.name} (Model: {serie.id_car_model.name}, "
f"Make: {serie.id_car_model.id_car_make.name})"
)
# Export data if requested
if export:
# Export makes without models
if makes_without_models_count > 0:
filepath = os.path.join(export_dir, "makes_without_models.csv")
with open(filepath, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["make_id", "make_name", "is_sa_import"])
for make in makes_without_models:
writer.writerow(
[make.id_car_make, make.name, make.is_sa_import]
)
self.stdout.write(
self.style.SUCCESS(f"Exported makes without models to {filepath}")
)
# Export models without series
if models_without_series_count > 0:
filepath = os.path.join(export_dir, "models_without_series.csv")
with open(filepath, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["model_id", "model_name", "make_id", "make_name"])
for model in models_without_series:
writer.writerow(
[
model.id_car_model,
model.name,
model.id_car_make.id_car_make,
model.id_car_make.name,
]
)
self.stdout.write(
self.style.SUCCESS(f"Exported models without series to {filepath}")
)
# Export series without trims
if series_without_trims_count > 0:
filepath = os.path.join(export_dir, "series_without_trims.csv")
with open(filepath, "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(
[
"serie_id",
"serie_name",
"model_id",
"model_name",
"make_id",
"make_name",
]
)
for serie in series_without_trims:
writer.writerow(
[
serie.id_car_serie,
serie.name,
serie.id_car_model.id_car_model,
serie.id_car_model.name,
serie.id_car_model.id_car_make.id_car_make,
serie.id_car_model.id_car_make.name,
]
)
self.stdout.write(
self.style.SUCCESS(f"Exported series without trims to {filepath}")
)
# Summary
self.stdout.write("\n" + "=" * 50)
self.stdout.write(self.style.SUCCESS("SUMMARY"))
self.stdout.write("=" * 50)
self.stdout.write(
f"Total makes: {total_makes} | Without models: {makes_without_models_count} ({makes_without_models_count / total_makes * 100:.2f}%)"
)
self.stdout.write(
f"Total models: {total_models} | Without series: {models_without_series_count} ({models_without_series_count / total_models * 100:.2f}%)"
)
self.stdout.write(
f"Total series: {total_series} | Without trims: {series_without_trims_count} ({series_without_trims_count / total_series * 100:.2f}%)"
)