add new fields for auto-evalution model #138

Merged
xoliqberdiyev merged 1 commits from behruz into main 2026-05-05 12:07:47 +00:00
6 changed files with 401 additions and 43 deletions

View File

@@ -55,7 +55,7 @@ class AutoEvaluationAdmin(ModelAdmin):
"fields": (
"tex_passport_serie_num",
("tex_passport_gived_date", "tex_passport_gived_location"),
("car_type", "car_wheel"),
("car_wheel",),
("car_brand", "car_model"),
("car_number", "manufacture_year"),
("car_dvigatel_number", "car_color"),

View File

@@ -6,6 +6,8 @@ class AutoObjectType(models.TextChoices):
LIGHTWEIGHT_AUTO = "lightweight_auto", _("Yengil automobil")
TRUCK_CAR = "truck_car", _("Yuk automobil")
SPECIAL_TECH = "special_tech", _("Maxsus texnika")
BUS = "bus", _("Avtobus")
MOTO = "moto", _("Mototsikl")
class AutoEvaluationStatus(models.TextChoices):

View File

@@ -0,0 +1,167 @@
# Generated by Django 5.2.7 on 2026-05-05 12:06
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("evaluation", "0043_mechanicautoevaluationmodel_and_more"),
]
operations = [
migrations.RemoveField(
model_name="autoevaluationmodel",
name="car_type",
),
migrations.RemoveField(
model_name="autoevaluationmodel",
name="tex_passport_file",
),
migrations.AddField(
model_name="autoevaluationmodel",
name="assessment_task_type",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="evaluation_auto_assessment_task_type",
to="evaluation.referenceitemmodel",
verbose_name="assessment task type",
),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="body_type",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="evaluation_auto_body_type",
to="evaluation.referenceitemmodel",
verbose_name="body type",
),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="car_position",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="evaluation_auto_car_position",
to="evaluation.referenceitemmodel",
verbose_name="car position",
),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="distance_covered",
field=models.PositiveIntegerField(blank=True, null=True, verbose_name="distance covered"),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="fuel_type",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="evaluation_auto_fuel_type",
to="evaluation.referenceitemmodel",
verbose_name="fuel type",
),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="object_owner_residence",
field=models.CharField(blank=True, max_length=255, null=True, verbose_name="object owner residence"),
),
migrations.AddField(
model_name="autoevaluationmodel",
name="state_car",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="evaluation_auto_state_car",
to="evaluation.referenceitemmodel",
verbose_name="state car",
),
),
migrations.AlterField(
model_name="autoevaluationmodel",
name="object_type",
field=models.CharField(
blank=True,
choices=[
("lightweight_auto", "Yengil automobil"),
("truck_car", "Yuk automobil"),
("special_tech", "Maxsus texnika"),
("bus", "Avtobus"),
("moto", "Mototsikl"),
],
max_length=50,
null=True,
verbose_name="object type",
),
),
migrations.AlterField(
model_name="bonuscategory",
name="category",
field=models.CharField(
choices=[
("lightweight_auto", "Yengil automobil"),
("truck_car", "Yuk automobil"),
("special_tech", "Maxsus texnika"),
("bus", "Avtobus"),
("moto", "Mototsikl"),
],
max_length=50,
),
),
migrations.AlterField(
model_name="mechanicautoevaluationmodel",
name="object_type",
field=models.CharField(
blank=True,
choices=[
("lightweight_auto", "Yengil automobil"),
("truck_car", "Yuk automobil"),
("special_tech", "Maxsus texnika"),
("bus", "Avtobus"),
("moto", "Mototsikl"),
],
max_length=50,
null=True,
verbose_name="object type",
),
),
migrations.CreateModel(
name="AutoEvaluationTexPassportFile",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"file",
models.FileField(
upload_to="auto_evaluation/tech_passports/%Y/%m/", verbose_name="tech passport file"
),
),
(
"auto_evaluation",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="tex_passport_files",
to="evaluation.autoevaluationmodel",
),
),
],
options={
"verbose_name": "Auto Evaluation Tex Passport File",
"verbose_name_plural": "Auto Evaluation Tex Passport Files",
"db_table": "AutoEvaluationTexPassportFile",
},
),
]

View File

@@ -4,7 +4,6 @@ from django_core.models import AbstractBaseModel
from model_bakery import baker
from core.apps.evaluation.choices.auto import (
AutoCarType,
AutoCarWheel,
AutoEvaluationStatus,
AutoObjectType,
@@ -54,12 +53,57 @@ class AutoEvaluationModel(AbstractBaseModel):
null=True,
)
tex_passport_file = models.FileField(
verbose_name=_("tech passport file"),
upload_to="quick_evaluation/tech_passports/%Y/%m/",
distance_covered = models.PositiveIntegerField(
verbose_name=_("distance covered"),
blank=True,
null=True,
)
object_owner_residence = models.CharField(
verbose_name=_("object owner residence"),
max_length=255,
blank=True,
null=True,
)
car_position = models.ForeignKey(
'evaluation.ReferenceitemModel',
verbose_name=_("car position"),
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='evaluation_auto_car_position',
)
body_type = models.ForeignKey(
'evaluation.ReferenceitemModel',
verbose_name=_("body type"),
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='evaluation_auto_body_type',
)
fuel_type = models.ForeignKey(
'evaluation.ReferenceitemModel',
verbose_name=_("fuel type"),
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='evaluation_auto_fuel_type',
)
state_car = models.ForeignKey(
'evaluation.ReferenceitemModel',
verbose_name=_("state car"),
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='evaluation_auto_state_car',
)
assessment_task_type = models.ForeignKey(
'evaluation.ReferenceitemModel',
verbose_name=_("assessment task type"),
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='evaluation_auto_assessment_task_type',
)
# ── Step 1 — Umumiy ma'lumotlar ──────────────────────────────────
registration_number = models.CharField(
@@ -174,12 +218,6 @@ class AutoEvaluationModel(AbstractBaseModel):
blank=True,
null=True,
)
car_type = models.IntegerField(
verbose_name=_("car type"),
choices=AutoCarType.choices,
blank=True,
null=True,
)
car_wheel = models.IntegerField(
verbose_name=_("car wheel"),
choices=AutoCarWheel.choices,
@@ -252,3 +290,27 @@ class AutoEvaluationModel(AbstractBaseModel):
db_table = "AutoEvaluation"
verbose_name = _("Auto Evaluation")
verbose_name_plural = _("Auto Evaluations")
class AutoEvaluationTexPassportFile(AbstractBaseModel):
auto_evaluation = models.ForeignKey(
AutoEvaluationModel,
on_delete=models.CASCADE,
related_name="tex_passport_files",
)
file = models.FileField(
verbose_name=_("tech passport file"),
upload_to="auto_evaluation/tech_passports/%Y/%m/",
)
def __str__(self):
return f"Tex passport file for AutoEvaluation #{self.auto_evaluation_id}"
@classmethod
def _baker(cls):
return baker.make(cls)
class Meta:
db_table = "AutoEvaluationTexPassportFile"
verbose_name = _("Auto Evaluation Tex Passport File")
verbose_name_plural = _("Auto Evaluation Tex Passport Files")

View File

@@ -3,13 +3,36 @@ import re
from django.contrib.auth import get_user_model
from rest_framework import serializers
from django.db import transaction
from core.apps.evaluation.choices.request import RequestStatus
from core.apps.evaluation.models import AutoEvaluationModel, ReferenceitemModel, EvaluationrequestModel
from core.apps.evaluation.models import (
AutoEvaluationModel,
AutoEvaluationTexPassportFile,
ReferenceitemModel,
EvaluationrequestModel,
)
from core.apps.evaluation.serializers.reference import ListReferenceitemSerializer
User = get_user_model()
class AutoEvaluationTexPassportFileSerializer(serializers.ModelSerializer):
file = serializers.SerializerMethodField()
class Meta:
model = AutoEvaluationTexPassportFile
fields = ["id", "file"]
def get_file(self, obj):
request = self.context.get("request")
if not obj.file:
return None
if request:
return request.build_absolute_uri(obj.file.url)
return obj.file.url
class BaseAutoevaluationSerializer(serializers.ModelSerializer):
status_display = serializers.CharField(source="get_status_display", read_only=True)
object_type_display = serializers.CharField(source="get_object_type_display", read_only=True, default=None)
@@ -17,6 +40,12 @@ class BaseAutoevaluationSerializer(serializers.ModelSerializer):
default=None)
rate_type = ListReferenceitemSerializer(read_only=True)
value_determined = ListReferenceitemSerializer(read_only=True)
car_position = ListReferenceitemSerializer(read_only=True)
body_type = ListReferenceitemSerializer(read_only=True)
fuel_type = ListReferenceitemSerializer(read_only=True)
state_car = ListReferenceitemSerializer(read_only=True)
assessment_task_type = ListReferenceitemSerializer(read_only=True)
tex_passport_files = AutoEvaluationTexPassportFileSerializer(many=True, read_only=True)
user = serializers.SerializerMethodField(method_name="get_user", read_only=True)
class Meta:
@@ -32,7 +61,9 @@ class BaseAutoevaluationSerializer(serializers.ModelSerializer):
"object_owner_individual_person_p_name",
"object_owner_legal_entity",
"object_owner_legal_inn",
"object_owner_residence",
"tex_passport_serie_num",
"tex_passport_files",
"rating_goal",
"registration_number",
"object_type",
@@ -42,6 +73,12 @@ class BaseAutoevaluationSerializer(serializers.ModelSerializer):
"car_number",
"manufacture_year",
"car_color",
"distance_covered",
"car_position",
"body_type",
"fuel_type",
"state_car",
"assessment_task_type",
"status",
"status_display",
"created_at",
@@ -68,7 +105,6 @@ class ListAutoevaluationSerializer(BaseAutoevaluationSerializer):
class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
car_type_display = serializers.CharField(source="get_car_type_display", read_only=True, default=None)
car_wheel_display = serializers.CharField(source="get_car_wheel_display", read_only=True, default=None)
class Meta(BaseAutoevaluationSerializer.Meta):
@@ -89,11 +125,8 @@ class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
"object_owner_legal_inn",
# Step 4
"tex_passport_serie_num",
"tex_passport_file",
"tex_passport_gived_date",
"tex_passport_gived_location",
"car_type",
"car_type_display",
"car_wheel",
"car_wheel_display",
"car_dvigatel_number",
@@ -106,11 +139,6 @@ class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
value_determined = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
value_determined = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
@@ -121,6 +149,36 @@ class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
required=False,
allow_null=True,
)
car_position = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
body_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
fuel_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
state_car = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
assessment_task_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
tex_passport_files = serializers.ListField(
child=serializers.FileField(),
required=False,
write_only=True,
)
class Meta:
model = AutoEvaluationModel
@@ -140,14 +198,15 @@ class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
"object_owner_individual_person_passport_num",
"object_owner_legal_entity",
"object_owner_legal_inn",
"object_owner_residence",
"value_determined",
"rate_type",
"assessment_task_type",
# Step 4
"tex_passport_file",
"tex_passport_files",
"tex_passport_serie_num",
"tex_passport_gived_date",
"tex_passport_gived_location",
"car_type",
"car_wheel",
"car_brand",
"car_model",
@@ -155,6 +214,11 @@ class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
"manufacture_year",
"car_dvigatel_number",
"car_color",
"distance_covered",
"car_position",
"body_type",
"fuel_type",
"state_car",
]
def validate_tex_passport_serie_num(self, value):
@@ -199,13 +263,23 @@ class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
return attrs
def update(self, instance, validated_data):
files = validated_data.pop("tex_passport_files", None)
with transaction.atomic():
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
if files is not None:
AutoEvaluationTexPassportFile.objects.bulk_create([
AutoEvaluationTexPassportFile(auto_evaluation=instance, file=f) for f in files
])
return instance
def to_representation(self, instance):
return RetrieveAutoevaluationSerializer(instance, context=self.context).data
class CreateAutoevaluationSerializer(serializers.ModelSerializer):
value_determined = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
value_determined = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
@@ -216,11 +290,41 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
required=False,
allow_null=True,
)
car_position = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
body_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
fuel_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
state_car = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
assessment_task_type = serializers.PrimaryKeyRelatedField(
queryset=ReferenceitemModel.objects.all(),
required=False,
allow_null=True,
)
evaluation_request = serializers.PrimaryKeyRelatedField(
queryset=EvaluationrequestModel.objects.all(),
required=False,
allow_null=True,
)
tex_passport_files = serializers.ListField(
child=serializers.FileField(),
required=False,
write_only=True,
)
class Meta:
model = AutoEvaluationModel
@@ -241,14 +345,15 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
"object_owner_individual_person_passport_num",
"object_owner_legal_entity",
"object_owner_legal_inn",
"object_owner_residence",
"value_determined",
"rate_type",
"assessment_task_type",
# Step 4
"tex_passport_serie_num",
"tex_passport_file",
"tex_passport_files",
"tex_passport_gived_date",
"tex_passport_gived_location",
"car_type",
"car_wheel",
"car_brand",
"car_model",
@@ -256,6 +361,11 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
"manufacture_year",
"car_dvigatel_number",
"car_color",
"distance_covered",
"car_position",
"body_type",
"fuel_type",
"state_car",
]
def validate_tex_passport_serie_num(self, value):
@@ -300,13 +410,23 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
return attrs
def create(self, validated_data):
files = validated_data.pop("tex_passport_files", [])
user = self.context.get('request').user
validated_data['user'] = user
evaluation_req = validated_data.get("evaluation_request")
if evaluation_req:
evaluation_req.status = RequestStatus.IN_PROGRESS
evaluation_req.save()
return super().create(validated_data)
with transaction.atomic():
instance = super().create(validated_data)
if files:
AutoEvaluationTexPassportFile.objects.bulk_create([
AutoEvaluationTexPassportFile(auto_evaluation=instance, file=f) for f in files
])
return instance
def to_representation(self, instance):
return RetrieveAutoevaluationSerializer(instance, context=self.context).data
class AutoEvaluationAppraisersSerializer(serializers.Serializer):
@@ -343,8 +463,7 @@ class AutoEvaluationModelSerializer(serializers.ModelSerializer):
class Meta:
model = AutoEvaluationModel
fields = ("tex_passport_file",
fields = (
"registration_number",
"contract_date",
"object_inspection_date",
@@ -359,13 +478,14 @@ class AutoEvaluationModelSerializer(serializers.ModelSerializer):
"object_owner_individual_person_passport_num",
"object_owner_legal_entity",
"object_owner_legal_inn",
"object_owner_residence",
"value_determined",
"rate_type",
"assessment_task_type",
"tex_passport_serie_num",
"tex_passport_gived_date",
"tex_passport_gived_location",
"car_type",
"car_wheel",
"car_brand",
"car_model",
@@ -373,6 +493,11 @@ class AutoEvaluationModelSerializer(serializers.ModelSerializer):
"manufacture_year",
"car_dvigatel_number",
"car_color",
"distance_covered",
"car_position",
"body_type",
"fuel_type",
"state_car",
"rating_goal",
"status",

View File

@@ -1,11 +1,13 @@
Mexanik avto baholash yaratish'ga "user" field qo'shish kerak
/v1/auto-evaluation/ field qo'shish va o'zgartirish kerak
API: /api/v1/mechanic-auto-evaluation/
Quyidagilar bolsin:
1. List da ushbu field kelishi kerak. id emas object kelsin
2. details boyicha get qilinganida ham kelsin. id emas object kelsin
3. edit qilishda ham ushbu field ni yanlash imkoni bolsin
object_type => Bu hozirda select. Oshanga value qoshish kerak: bus, moto
car_position => Qoshish kerak. Bu hozirda select. /api/v1/reference-item/ apidan value yuboraman
distance_covered => Qoshish kerak. Number. Bosib otilgan masofasi
body_type => Qoshish kerak. Bu hozirda select. /api/v1/reference-item/ apidan value yuboraman
fuel_type => Qoshish kerak. Bu hozirda select. /api/v1/reference-item/ apidan value yuboraman
state_car => Qoshish kerak. Bu hozirda select. /api/v1/reference-item/ apidan value yuboraman
car_type => manashu field ni olib tashlash kerak
tex_passport_file => multiple qilish kerak
assessment_task_type => Baholash vazifasi. Qoshish kerak. Select boladi. /api/v1/reference-item/ apidan value yuboraman
object_owner_residence => Obyekt egasi yashash joyi. Qoshish kerak. string boladi.