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}%)" )