140 lines
6.6 KiB
Python
140 lines
6.6 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}%)")
|