feat: add mechnic-auto-model
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
from .auto import * # noqa
|
from .auto import * # noqa
|
||||||
|
from .mechanic_auto import * # noqa
|
||||||
from .customer import * # noqa
|
from .customer import * # noqa
|
||||||
from .document import * # noqa
|
from .document import * # noqa
|
||||||
from .documentcategory import * # noqa
|
from .documentcategory import * # noqa
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
from django_filters import rest_framework as filters
|
from django_filters import rest_framework as filters
|
||||||
|
|
||||||
from core.apps.evaluation.choices.history import EvaluationEventType
|
from core.apps.evaluation.choices.history import EvaluationEventType
|
||||||
from core.apps.evaluation.models import AutoevaluationhistoryModel, QuickevaluationhistoryModel
|
from core.apps.evaluation.models import (
|
||||||
|
AutoevaluationhistoryModel,
|
||||||
|
MechanicAutoevaluationhistoryModel,
|
||||||
|
QuickevaluationhistoryModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AutoevaluationhistoryFilter(filters.FilterSet):
|
class AutoevaluationhistoryFilter(filters.FilterSet):
|
||||||
@@ -29,6 +33,31 @@ class AutoevaluationhistoryFilter(filters.FilterSet):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoevaluationhistoryFilter(filters.FilterSet):
|
||||||
|
mechanic_auto_evaluation = filters.NumberFilter(
|
||||||
|
field_name="mechanic_auto_evaluation", lookup_expr="exact"
|
||||||
|
)
|
||||||
|
event_type = filters.ChoiceFilter(
|
||||||
|
field_name="event_type",
|
||||||
|
choices=EvaluationEventType.choices,
|
||||||
|
)
|
||||||
|
created_from = filters.DateTimeFilter(
|
||||||
|
field_name="created_at", lookup_expr="gte"
|
||||||
|
)
|
||||||
|
created_to = filters.DateTimeFilter(
|
||||||
|
field_name="created_at", lookup_expr="lte"
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoevaluationhistoryModel
|
||||||
|
fields = [
|
||||||
|
"mechanic_auto_evaluation",
|
||||||
|
"event_type",
|
||||||
|
"created_from",
|
||||||
|
"created_to",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class QuickevaluationhistoryFilter(filters.FilterSet):
|
class QuickevaluationhistoryFilter(filters.FilterSet):
|
||||||
quick_evaluation = filters.NumberFilter(
|
quick_evaluation = filters.NumberFilter(
|
||||||
field_name="quick_evaluation", lookup_expr="exact"
|
field_name="quick_evaluation", lookup_expr="exact"
|
||||||
|
|||||||
37
core/apps/evaluation/filters/mechanic_auto.py
Normal file
37
core/apps/evaluation/filters/mechanic_auto.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from django_filters import rest_framework as filters
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import MechanicAutoEvaluationModel
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoevaluationFilter(filters.FilterSet):
|
||||||
|
status = filters.CharFilter(method="filter_status")
|
||||||
|
object_type = filters.CharFilter(field_name="object_type", lookup_expr="exact")
|
||||||
|
object_owner_type = filters.NumberFilter(field_name="object_owner_type", lookup_expr="exact")
|
||||||
|
rate_type = filters.NumberFilter(field_name="rate_type", lookup_expr="exact")
|
||||||
|
value_determined = filters.NumberFilter(field_name="value_determined", lookup_expr="exact")
|
||||||
|
client = filters.NumberFilter(field_name="valuation__customer", lookup_expr="exact")
|
||||||
|
created_from = filters.DateFilter(field_name="created_at", lookup_expr="gte")
|
||||||
|
created_to = filters.DateFilter(field_name="created_at", lookup_expr="lte")
|
||||||
|
rate_date_from = filters.DateFilter(field_name="rate_date", lookup_expr="gte")
|
||||||
|
rate_date_to = filters.DateFilter(field_name="rate_date", lookup_expr="lte")
|
||||||
|
|
||||||
|
def filter_status(self, queryset, name, value):
|
||||||
|
if value:
|
||||||
|
statuses = [s.strip() for s in value.split(",") if s.strip()]
|
||||||
|
return queryset.filter(status__in=statuses)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoEvaluationModel
|
||||||
|
fields = [
|
||||||
|
"status",
|
||||||
|
"object_type",
|
||||||
|
"object_owner_type",
|
||||||
|
"rate_type",
|
||||||
|
"value_determined",
|
||||||
|
"client",
|
||||||
|
"created_from",
|
||||||
|
"created_to",
|
||||||
|
"rate_date_from",
|
||||||
|
"rate_date_to",
|
||||||
|
]
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-05-05 11:52
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("evaluation", "0042_alter_bonuscategory_category"),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="MechanicAutoEvaluationModel",
|
||||||
|
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)),
|
||||||
|
(
|
||||||
|
"tex_passport_file",
|
||||||
|
models.FileField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
upload_to="mechanic_evaluation/tech_passports/%Y/%m/",
|
||||||
|
verbose_name="tech passport file",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"registration_number",
|
||||||
|
models.CharField(blank=True, max_length=50, null=True, verbose_name="registration number"),
|
||||||
|
),
|
||||||
|
("contract_date", models.DateField(blank=True, null=True, verbose_name="contract date")),
|
||||||
|
(
|
||||||
|
"object_inspection_date",
|
||||||
|
models.DateField(blank=True, null=True, verbose_name="object inspection date"),
|
||||||
|
),
|
||||||
|
("rate_date", models.DateField(blank=True, null=True, verbose_name="rate date")),
|
||||||
|
("rate_report_date", models.DateField(blank=True, null=True, verbose_name="rate report date")),
|
||||||
|
(
|
||||||
|
"object_type",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("lightweight_auto", "Yengil automobil"),
|
||||||
|
("truck_car", "Yuk automobil"),
|
||||||
|
("special_tech", "Maxsus texnika"),
|
||||||
|
],
|
||||||
|
max_length=50,
|
||||||
|
null=True,
|
||||||
|
verbose_name="object type",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_type",
|
||||||
|
models.IntegerField(
|
||||||
|
blank=True,
|
||||||
|
choices=[(1, "Jismoniy shaxs"), (2, "Yuridik shaxs")],
|
||||||
|
null=True,
|
||||||
|
verbose_name="object owner type",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
models.CharField(blank=True, max_length=100, null=True, verbose_name="owner first name"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
models.CharField(blank=True, max_length=100, null=True, verbose_name="owner last name"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
models.CharField(blank=True, max_length=100, null=True, verbose_name="owner patronymic"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
models.CharField(blank=True, max_length=20, null=True, verbose_name="owner passport number"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
models.CharField(blank=True, max_length=255, null=True, verbose_name="legal entity name"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
models.CharField(blank=True, max_length=20, null=True, verbose_name="legal entity INN"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
models.CharField(
|
||||||
|
blank=True, max_length=20, null=True, verbose_name="tech passport series and number"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tex_passport_gived_date",
|
||||||
|
models.DateField(blank=True, null=True, verbose_name="tech passport given date"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tex_passport_gived_location",
|
||||||
|
models.CharField(
|
||||||
|
blank=True, max_length=255, null=True, verbose_name="tech passport given location"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"car_type",
|
||||||
|
models.IntegerField(
|
||||||
|
blank=True, choices=[(1, "Xetchbek"), (2, "Universal")], null=True, verbose_name="car type"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"car_wheel",
|
||||||
|
models.IntegerField(blank=True, choices=[(1, "4x4")], null=True, verbose_name="car wheel"),
|
||||||
|
),
|
||||||
|
("car_brand", models.CharField(blank=True, max_length=100, null=True, verbose_name="car brand")),
|
||||||
|
("car_model", models.CharField(blank=True, max_length=100, null=True, verbose_name="car model")),
|
||||||
|
("car_number", models.CharField(blank=True, max_length=20, null=True, verbose_name="car number")),
|
||||||
|
(
|
||||||
|
"manufacture_year",
|
||||||
|
models.CharField(blank=True, max_length=10, null=True, verbose_name="manufacture year"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"car_dvigatel_number",
|
||||||
|
models.CharField(blank=True, max_length=50, null=True, verbose_name="engine number"),
|
||||||
|
),
|
||||||
|
("car_color", models.CharField(blank=True, max_length=50, null=True, verbose_name="car color")),
|
||||||
|
("rating_goal", models.CharField(blank=True, max_length=50, null=True, verbose_name="rating goal")),
|
||||||
|
(
|
||||||
|
"status",
|
||||||
|
models.CharField(
|
||||||
|
choices=[
|
||||||
|
("yaratildi", "Yaratildi"),
|
||||||
|
("baxolovchi_biriktirildi", "Baholovchi biriktirildi"),
|
||||||
|
("baxolandi", "Baholandi"),
|
||||||
|
("rad_etildi", "Rad etildi"),
|
||||||
|
("tasdiqlandi", "Tasdiqlandi"),
|
||||||
|
],
|
||||||
|
default="yaratildi",
|
||||||
|
max_length=50,
|
||||||
|
verbose_name="status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("is_archived", models.BooleanField(default=False, verbose_name="is archived")),
|
||||||
|
(
|
||||||
|
"appraisers",
|
||||||
|
models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
related_name="mechanic_auto_evaluation_appraisers",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
verbose_name="appraisers",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"evaluation_request",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="mechanic_auto_evaluations_request",
|
||||||
|
to="evaluation.evaluationrequestmodel",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"rate_type",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="evaluation_mechanic_auto_rate_type",
|
||||||
|
to="evaluation.referenceitemmodel",
|
||||||
|
verbose_name="rate type",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="mechanic_auto_evaluations_user",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"valuation",
|
||||||
|
models.OneToOneField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="mechanic_auto_detail",
|
||||||
|
to="evaluation.valuationmodel",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"value_determined",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
related_name="evaluation_mechanic_auto_value_determined",
|
||||||
|
to="evaluation.referenceitemmodel",
|
||||||
|
verbose_name="value determined",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"vehicle",
|
||||||
|
models.OneToOneField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="mechanic_evaluation",
|
||||||
|
to="evaluation.vehiclemodel",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "Mechanic Auto Evaluation",
|
||||||
|
"verbose_name_plural": "Mechanic Auto Evaluations",
|
||||||
|
"db_table": "MechanicAutoEvaluation",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="MechanicAutoevaluationhistoryModel",
|
||||||
|
fields=[
|
||||||
|
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
||||||
|
(
|
||||||
|
"event_type",
|
||||||
|
models.CharField(
|
||||||
|
choices=[
|
||||||
|
("order_created", "Buyurtma yaratildi"),
|
||||||
|
("status_changed", "Status o'zgartirildi"),
|
||||||
|
("evaluator_assigned", "Baholovchi biriktirildi"),
|
||||||
|
("document_uploaded", "Hujjat yuklandi"),
|
||||||
|
("payment_made", "To'lov qilindi"),
|
||||||
|
],
|
||||||
|
max_length=50,
|
||||||
|
verbose_name="event type",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("actor_id", models.BigIntegerField(blank=True, null=True, verbose_name="actor id")),
|
||||||
|
("actor_full_name", models.CharField(default="Tizim", max_length=255, verbose_name="actor full name")),
|
||||||
|
("actor_role", models.CharField(default="system", max_length=50, verbose_name="actor role")),
|
||||||
|
("meta", models.JSONField(blank=True, default=dict, verbose_name="meta")),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True, verbose_name="created at")),
|
||||||
|
(
|
||||||
|
"mechanic_auto_evaluation",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="history",
|
||||||
|
to="evaluation.mechanicautoevaluationmodel",
|
||||||
|
verbose_name="mechanic auto evaluation",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"verbose_name": "Mechanic Auto Evaluation History",
|
||||||
|
"verbose_name_plural": "Mechanic Auto Evaluation Histories",
|
||||||
|
"db_table": "MechanicAutoEvaluationHistory",
|
||||||
|
"ordering": ["created_at"],
|
||||||
|
"indexes": [
|
||||||
|
models.Index(
|
||||||
|
fields=["mechanic_auto_evaluation_id", "created_at"], name="mech_auto_hist_eval_date_idx"
|
||||||
|
),
|
||||||
|
models.Index(fields=["event_type"], name="mech_auto_hist_event_type_idx"),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
from .auto import * # noqa
|
from .auto import * # noqa
|
||||||
|
from .mechanic_auto import * # noqa
|
||||||
from .customer import * # noqa
|
from .customer import * # noqa
|
||||||
from .document import * # noqa
|
from .document import * # noqa
|
||||||
from .documentcategory import * # noqa
|
from .documentcategory import * # noqa
|
||||||
|
|||||||
@@ -69,6 +69,66 @@ class AutoevaluationhistoryModel(models.Model):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoevaluationhistoryModel(models.Model):
|
||||||
|
"""MechanicAutoEvaluation bo'yicha barcha harakatlar logi — faqat o'qiladi, signallar tomonidan yoziladi."""
|
||||||
|
|
||||||
|
mechanic_auto_evaluation = models.ForeignKey(
|
||||||
|
"evaluation.MechanicAutoEvaluationModel",
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="history",
|
||||||
|
verbose_name=_("mechanic auto evaluation"),
|
||||||
|
)
|
||||||
|
event_type = models.CharField(
|
||||||
|
verbose_name=_("event type"),
|
||||||
|
max_length=50,
|
||||||
|
choices=EvaluationEventType.choices,
|
||||||
|
)
|
||||||
|
|
||||||
|
actor_id = models.BigIntegerField(
|
||||||
|
verbose_name=_("actor id"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
actor_full_name = models.CharField(
|
||||||
|
verbose_name=_("actor full name"),
|
||||||
|
max_length=255,
|
||||||
|
default="Tizim",
|
||||||
|
)
|
||||||
|
actor_role = models.CharField(
|
||||||
|
verbose_name=_("actor role"),
|
||||||
|
max_length=50,
|
||||||
|
default="system",
|
||||||
|
)
|
||||||
|
|
||||||
|
meta = models.JSONField(
|
||||||
|
verbose_name=_("meta"),
|
||||||
|
default=dict,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
created_at = models.DateTimeField(
|
||||||
|
verbose_name=_("created at"),
|
||||||
|
auto_now_add=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.get_event_type_display()} — MechanicAutoEval #{self.mechanic_auto_evaluation_id}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _baker(cls):
|
||||||
|
return baker.make(cls)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "MechanicAutoEvaluationHistory"
|
||||||
|
verbose_name = _("Mechanic Auto Evaluation History")
|
||||||
|
verbose_name_plural = _("Mechanic Auto Evaluation Histories")
|
||||||
|
ordering = ["created_at"]
|
||||||
|
indexes = [
|
||||||
|
models.Index(fields=["mechanic_auto_evaluation_id", "created_at"], name="mech_auto_hist_eval_date_idx"),
|
||||||
|
models.Index(fields=["event_type"], name="mech_auto_hist_event_type_idx"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class QuickevaluationhistoryModel(models.Model):
|
class QuickevaluationhistoryModel(models.Model):
|
||||||
"""QuickEvaluation bo'yicha barcha harakatlar logi — faqat o'qiladi, signallar tomonidan yoziladi."""
|
"""QuickEvaluation bo'yicha barcha harakatlar logi — faqat o'qiladi, signallar tomonidan yoziladi."""
|
||||||
|
|
||||||
|
|||||||
250
core/apps/evaluation/models/mechanic_auto.py
Normal file
250
core/apps/evaluation/models/mechanic_auto.py
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django_core.models import AbstractBaseModel
|
||||||
|
from model_bakery import baker
|
||||||
|
|
||||||
|
from core.apps.evaluation.choices.auto import (
|
||||||
|
AutoCarType,
|
||||||
|
AutoCarWheel,
|
||||||
|
AutoEvaluationStatus,
|
||||||
|
AutoObjectType,
|
||||||
|
ObjectOwnerType,
|
||||||
|
)
|
||||||
|
from .valuation import ValuationModel
|
||||||
|
from .vehicle import VehicleModel
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoEvaluationModel(AbstractBaseModel):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
"accounts.User",
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
related_name="mechanic_auto_evaluations_user",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
evaluation_request = models.ForeignKey(
|
||||||
|
"evaluation.EvaluationRequestModel",
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
related_name="mechanic_auto_evaluations_request",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
valuation = models.OneToOneField(
|
||||||
|
ValuationModel,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="mechanic_auto_detail",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
vehicle = models.OneToOneField(
|
||||||
|
VehicleModel,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="mechanic_evaluation",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
appraisers = models.ManyToManyField(
|
||||||
|
"accounts.User",
|
||||||
|
verbose_name=_("appraisers"),
|
||||||
|
related_name="mechanic_auto_evaluation_appraisers",
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
tex_passport_file = models.FileField(
|
||||||
|
verbose_name=_("tech passport file"),
|
||||||
|
upload_to="mechanic_evaluation/tech_passports/%Y/%m/",
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Step 1 — Umumiy ma'lumotlar ──────────────────────────────────
|
||||||
|
registration_number = models.CharField(
|
||||||
|
verbose_name=_("registration number"),
|
||||||
|
max_length=50,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
contract_date = models.DateField(
|
||||||
|
verbose_name=_("contract date"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_inspection_date = models.DateField(
|
||||||
|
verbose_name=_("object inspection date"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
rate_date = models.DateField(
|
||||||
|
verbose_name=_("rate date"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
rate_report_date = models.DateField(
|
||||||
|
verbose_name=_("rate report date"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_type = models.CharField(
|
||||||
|
verbose_name=_("object type"),
|
||||||
|
max_length=50,
|
||||||
|
choices=AutoObjectType.choices,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Step 2 — Shaxs ma'lumotlari ─────────────────────────────────
|
||||||
|
object_owner_type = models.IntegerField(
|
||||||
|
verbose_name=_("object owner type"),
|
||||||
|
choices=ObjectOwnerType.choices,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_individual_person_f_name = models.CharField(
|
||||||
|
verbose_name=_("owner first name"),
|
||||||
|
max_length=100,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_individual_person_l_name = models.CharField(
|
||||||
|
verbose_name=_("owner last name"),
|
||||||
|
max_length=100,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_individual_person_p_name = models.CharField(
|
||||||
|
verbose_name=_("owner patronymic"),
|
||||||
|
max_length=100,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_individual_person_passport_num = models.CharField(
|
||||||
|
verbose_name=_("owner passport number"),
|
||||||
|
max_length=20,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_legal_entity = models.CharField(
|
||||||
|
verbose_name=_("legal entity name"),
|
||||||
|
max_length=255,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
object_owner_legal_inn = models.CharField(
|
||||||
|
verbose_name=_("legal entity INN"),
|
||||||
|
max_length=20,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
value_determined = models.ForeignKey(
|
||||||
|
'evaluation.ReferenceitemModel',
|
||||||
|
verbose_name=_("value determined"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
related_name='evaluation_mechanic_auto_value_determined'
|
||||||
|
)
|
||||||
|
rate_type = models.ForeignKey(
|
||||||
|
'evaluation.ReferenceitemModel',
|
||||||
|
verbose_name=_("rate type"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=models.SET_NULL,
|
||||||
|
related_name='evaluation_mechanic_auto_rate_type'
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Step 4 — Avtomobil ma'lumotlari ─────────────────────────────
|
||||||
|
tex_passport_serie_num = models.CharField(
|
||||||
|
verbose_name=_("tech passport series and number"),
|
||||||
|
max_length=20,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
tex_passport_gived_date = models.DateField(
|
||||||
|
verbose_name=_("tech passport given date"),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
tex_passport_gived_location = models.CharField(
|
||||||
|
verbose_name=_("tech passport given location"),
|
||||||
|
max_length=255,
|
||||||
|
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,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
car_brand = models.CharField(
|
||||||
|
verbose_name=_("car brand"),
|
||||||
|
max_length=100,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
car_model = models.CharField(
|
||||||
|
verbose_name=_("car model"),
|
||||||
|
max_length=100,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
car_number = models.CharField(
|
||||||
|
verbose_name=_("car number"),
|
||||||
|
max_length=20,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
manufacture_year = models.CharField(
|
||||||
|
verbose_name=_("manufacture year"),
|
||||||
|
max_length=10,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
car_dvigatel_number = models.CharField(
|
||||||
|
verbose_name=_("engine number"),
|
||||||
|
max_length=50,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
car_color = models.CharField(
|
||||||
|
verbose_name=_("car color"),
|
||||||
|
max_length=50,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Natija ───────────────────────────────────────────────────────
|
||||||
|
rating_goal = models.CharField(
|
||||||
|
verbose_name=_("rating goal"),
|
||||||
|
max_length=50,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
status = models.CharField(
|
||||||
|
verbose_name=_("status"),
|
||||||
|
max_length=50,
|
||||||
|
choices=AutoEvaluationStatus.choices,
|
||||||
|
default=AutoEvaluationStatus.CREATED,
|
||||||
|
)
|
||||||
|
is_archived = models.BooleanField(
|
||||||
|
verbose_name=_("is archived"),
|
||||||
|
default=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Mechanic Auto Evaluation {self.registration_number or self.pk}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _baker(cls):
|
||||||
|
return baker.make(cls)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "MechanicAutoEvaluation"
|
||||||
|
verbose_name = _("Mechanic Auto Evaluation")
|
||||||
|
verbose_name_plural = _("Mechanic Auto Evaluations")
|
||||||
364
core/apps/evaluation/serializers/auto/MechanicAutoEvaluation.py
Normal file
364
core/apps/evaluation/serializers/auto/MechanicAutoEvaluation.py
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.evaluation.choices.request import RequestStatus
|
||||||
|
from core.apps.evaluation.models import (
|
||||||
|
MechanicAutoEvaluationModel,
|
||||||
|
ReferenceitemModel,
|
||||||
|
EvaluationrequestModel,
|
||||||
|
)
|
||||||
|
from core.apps.evaluation.serializers.reference import ListReferenceitemSerializer
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
class BaseMechanicAutoevaluationSerializer(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)
|
||||||
|
object_owner_type_display = serializers.CharField(source="get_object_owner_type_display", read_only=True,
|
||||||
|
default=None)
|
||||||
|
rate_type = ListReferenceitemSerializer(read_only=True)
|
||||||
|
value_determined = ListReferenceitemSerializer(read_only=True)
|
||||||
|
user = serializers.SerializerMethodField(method_name="get_user", read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoEvaluationModel
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
"rating_goal",
|
||||||
|
"registration_number",
|
||||||
|
"object_type",
|
||||||
|
"object_type_display",
|
||||||
|
"car_brand",
|
||||||
|
"car_model",
|
||||||
|
"car_number",
|
||||||
|
"manufacture_year",
|
||||||
|
"car_color",
|
||||||
|
"status",
|
||||||
|
"status_display",
|
||||||
|
"created_at",
|
||||||
|
"value_determined",
|
||||||
|
"rate_type",
|
||||||
|
"user",
|
||||||
|
"evaluation_request",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_user(self, obj):
|
||||||
|
request = self.context.get('request')
|
||||||
|
return {
|
||||||
|
"id": obj.user.id,
|
||||||
|
"phone": obj.user.phone,
|
||||||
|
"first_name": obj.user.first_name,
|
||||||
|
"last_name": obj.user.last_name,
|
||||||
|
"avatar": request.build_absolute_uri(obj.user.avatar.url) if obj.user.avatar else None
|
||||||
|
} if obj.user else None
|
||||||
|
|
||||||
|
|
||||||
|
class ListMechanicAutoevaluationSerializer(BaseMechanicAutoevaluationSerializer):
|
||||||
|
class Meta(BaseMechanicAutoevaluationSerializer.Meta):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class RetrieveMechanicAutoevaluationSerializer(BaseMechanicAutoevaluationSerializer):
|
||||||
|
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(BaseMechanicAutoevaluationSerializer.Meta):
|
||||||
|
fields = BaseMechanicAutoevaluationSerializer.Meta.fields + [
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"rate_date",
|
||||||
|
"rate_report_date",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_type_display",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"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",
|
||||||
|
"valuation",
|
||||||
|
"vehicle",
|
||||||
|
"rating_goal",
|
||||||
|
"updated_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateMechanicAutoevaluationSerializer(serializers.ModelSerializer):
|
||||||
|
value_determined = serializers.PrimaryKeyRelatedField(
|
||||||
|
queryset=ReferenceitemModel.objects.all(),
|
||||||
|
required=False,
|
||||||
|
allow_null=True,
|
||||||
|
)
|
||||||
|
rate_type = serializers.PrimaryKeyRelatedField(
|
||||||
|
queryset=ReferenceitemModel.objects.all(),
|
||||||
|
required=False,
|
||||||
|
allow_null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoEvaluationModel
|
||||||
|
fields = [
|
||||||
|
"registration_number",
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"rate_date",
|
||||||
|
"rate_report_date",
|
||||||
|
"object_type",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"value_determined",
|
||||||
|
"rate_type",
|
||||||
|
"tex_passport_file",
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
"tex_passport_gived_date",
|
||||||
|
"tex_passport_gived_location",
|
||||||
|
"car_type",
|
||||||
|
"car_wheel",
|
||||||
|
"car_brand",
|
||||||
|
"car_model",
|
||||||
|
"car_number",
|
||||||
|
"manufacture_year",
|
||||||
|
"car_dvigatel_number",
|
||||||
|
"car_color",
|
||||||
|
]
|
||||||
|
|
||||||
|
def validate_tex_passport_serie_num(self, value):
|
||||||
|
if value and not re.match(r"^[A-Z]{3}\s?\d{7}$", value):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
"Format: AAA 1234567 (3 harf + 7 raqam)"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def validate_object_owner_individual_person_passport_num(self, value):
|
||||||
|
if value and not re.match(r"^[A-Z]{2}\s?\d{7}$", value):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
"Format: AA 1234567 (2 harf + 7 raqam)"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
owner_type = attrs.get("object_owner_type")
|
||||||
|
|
||||||
|
if owner_type == 1:
|
||||||
|
required_fields = {
|
||||||
|
"object_owner_individual_person_f_name": "Ismi",
|
||||||
|
"object_owner_individual_person_l_name": "Familiyasi",
|
||||||
|
"object_owner_individual_person_p_name": "Sharifi",
|
||||||
|
"object_owner_individual_person_passport_num": "Passport raqami",
|
||||||
|
}
|
||||||
|
for field, label in required_fields.items():
|
||||||
|
if not attrs.get(field):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{field: f"Jismoniy shaxs uchun {label} majburiy."}
|
||||||
|
)
|
||||||
|
|
||||||
|
elif owner_type == 2:
|
||||||
|
if not attrs.get("object_owner_legal_entity"):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{"object_owner_legal_entity": "Yuridik shaxs nomi majburiy."}
|
||||||
|
)
|
||||||
|
if not attrs.get("object_owner_legal_inn"):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{"object_owner_legal_inn": "INN raqami majburiy."}
|
||||||
|
)
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
class CreateMechanicAutoevaluationSerializer(serializers.ModelSerializer):
|
||||||
|
value_determined = serializers.PrimaryKeyRelatedField(
|
||||||
|
queryset=ReferenceitemModel.objects.all(),
|
||||||
|
required=False,
|
||||||
|
allow_null=True,
|
||||||
|
)
|
||||||
|
rate_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,
|
||||||
|
)
|
||||||
|
user = serializers.PrimaryKeyRelatedField(
|
||||||
|
queryset=User.objects.all(),
|
||||||
|
required=True,
|
||||||
|
allow_null=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoEvaluationModel
|
||||||
|
fields = [
|
||||||
|
"user",
|
||||||
|
"registration_number",
|
||||||
|
"evaluation_request",
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"rate_date",
|
||||||
|
"rate_report_date",
|
||||||
|
"object_type",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"value_determined",
|
||||||
|
"rate_type",
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
"tex_passport_file",
|
||||||
|
"tex_passport_gived_date",
|
||||||
|
"tex_passport_gived_location",
|
||||||
|
"car_type",
|
||||||
|
"car_wheel",
|
||||||
|
"car_brand",
|
||||||
|
"car_model",
|
||||||
|
"car_number",
|
||||||
|
"manufacture_year",
|
||||||
|
"car_dvigatel_number",
|
||||||
|
"car_color",
|
||||||
|
]
|
||||||
|
|
||||||
|
def validate_tex_passport_serie_num(self, value):
|
||||||
|
if value and not re.match(r"^[A-Z]{3}\s?\d{7}$", value):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
"Format: AAA 1234567 (3 harf + 7 raqam)"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def validate_object_owner_individual_person_passport_num(self, value):
|
||||||
|
if value and not re.match(r"^[A-Z]{2}\s?\d{7}$", value):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
"Format: AA 1234567 (2 harf + 7 raqam)"
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
owner_type = attrs.get("object_owner_type")
|
||||||
|
if owner_type == 1:
|
||||||
|
required_fields = {
|
||||||
|
"object_owner_individual_person_f_name": "Ismi",
|
||||||
|
"object_owner_individual_person_l_name": "Familiyasi",
|
||||||
|
"object_owner_individual_person_p_name": "Sharifi",
|
||||||
|
"object_owner_individual_person_passport_num": "Passport raqami",
|
||||||
|
}
|
||||||
|
for field, label in required_fields.items():
|
||||||
|
if not attrs.get(field):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{field: f"Jismoniy shaxs uchun {label} majburiy."}
|
||||||
|
)
|
||||||
|
|
||||||
|
elif owner_type == 2:
|
||||||
|
if not attrs.get("object_owner_legal_entity"):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{"object_owner_legal_entity": "Yuridik shaxs nomi majburiy."}
|
||||||
|
)
|
||||||
|
if not attrs.get("object_owner_legal_inn"):
|
||||||
|
raise serializers.ValidationError(
|
||||||
|
{"object_owner_legal_inn": "INN raqami majburiy."}
|
||||||
|
)
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
evaluation_req = validated_data.get("evaluation_request")
|
||||||
|
if evaluation_req:
|
||||||
|
evaluation_req.status = RequestStatus.IN_PROGRESS
|
||||||
|
evaluation_req.save()
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoEvaluationAppraisersSerializer(serializers.Serializer):
|
||||||
|
ids = serializers.ListField(child=serializers.IntegerField())
|
||||||
|
|
||||||
|
def validate(self, data):
|
||||||
|
if not data.get("ids"):
|
||||||
|
raise serializers.ValidationError("Appraisers IDs are required.")
|
||||||
|
users = User.objects.filter(id__in=data["ids"])
|
||||||
|
if not users:
|
||||||
|
raise serializers.ValidationError("Invalid appraisers IDs.")
|
||||||
|
data['users'] = users
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class MechanicAutoEvaluationModelSerializer(serializers.ModelSerializer):
|
||||||
|
user = serializers.StringRelatedField(read_only=True)
|
||||||
|
appraisers = serializers.PrimaryKeyRelatedField(
|
||||||
|
many=True,
|
||||||
|
queryset=User.objects.all(),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoEvaluationModel
|
||||||
|
fields = (
|
||||||
|
"tex_passport_file",
|
||||||
|
"registration_number",
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"rate_date",
|
||||||
|
"rate_report_date",
|
||||||
|
"object_type",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"value_determined",
|
||||||
|
"rate_type",
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
"tex_passport_gived_date",
|
||||||
|
"tex_passport_gived_location",
|
||||||
|
"car_type",
|
||||||
|
"car_wheel",
|
||||||
|
"car_brand",
|
||||||
|
"car_model",
|
||||||
|
"car_number",
|
||||||
|
"manufacture_year",
|
||||||
|
"car_dvigatel_number",
|
||||||
|
"car_color",
|
||||||
|
"rating_goal",
|
||||||
|
"status",
|
||||||
|
"is_archived",
|
||||||
|
"user",
|
||||||
|
"appraisers",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
)
|
||||||
|
|
||||||
|
read_only_fields = (
|
||||||
|
"id",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
)
|
||||||
@@ -1 +1,2 @@
|
|||||||
from .AutoEvaluation import * # noqa
|
from .AutoEvaluation import * # noqa
|
||||||
|
from .MechanicAutoEvaluation import * # noqa
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import MechanicAutoevaluationhistoryModel
|
||||||
|
|
||||||
|
|
||||||
|
class BaseMechanicAutoevaluationhistorySerializer(serializers.ModelSerializer):
|
||||||
|
event_type_display = serializers.CharField(source="get_event_type_display", read_only=True)
|
||||||
|
actor = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
def get_actor(self, obj):
|
||||||
|
return {
|
||||||
|
"id": obj.actor_id,
|
||||||
|
"full_name": obj.actor_full_name,
|
||||||
|
"role": obj.actor_role,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = MechanicAutoevaluationhistoryModel
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
"event_type",
|
||||||
|
"event_type_display",
|
||||||
|
"actor",
|
||||||
|
"meta",
|
||||||
|
"created_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ListMechanicAutoevaluationhistorySerializer(BaseMechanicAutoevaluationhistorySerializer):
|
||||||
|
class Meta(BaseMechanicAutoevaluationhistorySerializer.Meta): ...
|
||||||
|
|
||||||
|
|
||||||
|
class RetrieveMechanicAutoevaluationhistorySerializer(BaseMechanicAutoevaluationhistorySerializer):
|
||||||
|
class Meta(BaseMechanicAutoevaluationhistorySerializer.Meta):
|
||||||
|
fields = BaseMechanicAutoevaluationhistorySerializer.Meta.fields + ["mechanic_auto_evaluation"]
|
||||||
|
|
||||||
|
|
||||||
|
class CreateMechanicAutoevaluationhistorySerializer(BaseMechanicAutoevaluationhistorySerializer):
|
||||||
|
class Meta(BaseMechanicAutoevaluationhistorySerializer.Meta): ...
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
from .AutoEvaluationHistory import * # noqa
|
from .AutoEvaluationHistory import * # noqa
|
||||||
|
from .MechanicAutoEvaluationHistory import * # noqa
|
||||||
from .QuickEvaluationHistory import * # noqa
|
from .QuickEvaluationHistory import * # noqa
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ router = DefaultRouter()
|
|||||||
router.register("document-category", views.DocumentCategoryView, basename="DocumentCategory")
|
router.register("document-category", views.DocumentCategoryView, basename="DocumentCategory")
|
||||||
router.register("document", views.DocumentView, basename="Document")
|
router.register("document", views.DocumentView, basename="Document")
|
||||||
router.register("auto-evaluation-history", views.AutoEvaluationHistoryView, basename="auto-evaluation-history")
|
router.register("auto-evaluation-history", views.AutoEvaluationHistoryView, basename="auto-evaluation-history")
|
||||||
|
router.register("mechanic-auto-evaluation-history", views.MechanicAutoEvaluationHistoryView, basename="mechanic-auto-evaluation-history")
|
||||||
router.register("quick-evaluation-history", views.QuickEvaluationHistoryView, basename="quick-evaluation-history")
|
router.register("quick-evaluation-history", views.QuickEvaluationHistoryView, basename="quick-evaluation-history")
|
||||||
router.register("determined-value", views.DeterminedValueView, basename="determined-value")
|
router.register("determined-value", views.DeterminedValueView, basename="determined-value")
|
||||||
router.register("evaluation-purpose", views.EvaluationPurposeView, basename="evaluation-purpose")
|
router.register("evaluation-purpose", views.EvaluationPurposeView, basename="evaluation-purpose")
|
||||||
@@ -22,6 +23,7 @@ router.register("quick-evaluation", views.QuickEvaluationView, basename="quick-e
|
|||||||
router.register("movable-property-evaluation", views.MovablePropertyEvaluationView, basename="movable-property-evaluation")
|
router.register("movable-property-evaluation", views.MovablePropertyEvaluationView, basename="movable-property-evaluation")
|
||||||
router.register("real-estate-evaluation", views.RealEstateEvaluationView, basename="real-estate-evaluation")
|
router.register("real-estate-evaluation", views.RealEstateEvaluationView, basename="real-estate-evaluation")
|
||||||
router.register("auto-evaluation", views.AutoEvaluationView, basename="auto-evaluation")
|
router.register("auto-evaluation", views.AutoEvaluationView, basename="auto-evaluation")
|
||||||
|
router.register("mechanic-auto-evaluation", views.MechanicAutoEvaluationView, basename="mechanic-auto-evaluation")
|
||||||
router.register("vehicle", views.VehicleView, basename="vehicle")
|
router.register("vehicle", views.VehicleView, basename="vehicle")
|
||||||
router.register("valuation", views.ValuationView, basename="valuation")
|
router.register("valuation", views.ValuationView, basename="valuation")
|
||||||
router.register("property-owner", views.PropertyOwnerView, basename="property-owner")
|
router.register("property-owner", views.PropertyOwnerView, basename="property-owner")
|
||||||
@@ -72,6 +74,26 @@ urlpatterns = [
|
|||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
# Mechanic Auto Evaluation
|
||||||
|
path("mechanic-auto-evaluation/", include(
|
||||||
|
[
|
||||||
|
path("admin/", views.AdminMechanicEvaluationsAPIView.as_view(), name="admin-mechanic-evaluations"),
|
||||||
|
path('archive/', include(
|
||||||
|
[
|
||||||
|
path('<int:pk>/', views.MechanicAutoEvaluationArchiveAPIView.as_view()),
|
||||||
|
path('list/', views.MechanicAutoEvaluationArchivedListAPIView.as_view())
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
path('appraisers/', include(
|
||||||
|
[
|
||||||
|
path("<int:id>/list/", views.MechanicAutoEvaluationListAppraisersView.as_view()),
|
||||||
|
path("<int:id>/set/", views.MechanicAutoEvaluationSetAppraisersView.as_view()),
|
||||||
|
path("<int:id>/remove/", views.MechanicAutoEvaluationRemoveAppraisersView.as_view()),
|
||||||
|
]
|
||||||
|
))
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
|
||||||
# Evaluation Request
|
# Evaluation Request
|
||||||
path("evaluation-request/", include(
|
path("evaluation-request/", include(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from .auto import * # noqa
|
from .auto import * # noqa
|
||||||
|
from .mechanic_auto import * # noqa
|
||||||
from .customer import * # noqa
|
from .customer import * # noqa
|
||||||
from .document import * # noqa
|
from .document import * # noqa
|
||||||
from .documentcategory import * # noqa
|
from .documentcategory import * # noqa
|
||||||
|
|||||||
@@ -16,9 +16,14 @@ from rest_framework.viewsets import ReadOnlyModelViewSet
|
|||||||
# core apps
|
# core apps
|
||||||
from core.apps.evaluation.filters.history import (
|
from core.apps.evaluation.filters.history import (
|
||||||
AutoevaluationhistoryFilter,
|
AutoevaluationhistoryFilter,
|
||||||
|
MechanicAutoevaluationhistoryFilter,
|
||||||
QuickevaluationhistoryFilter,
|
QuickevaluationhistoryFilter,
|
||||||
)
|
)
|
||||||
from core.apps.evaluation.models import AutoevaluationhistoryModel, QuickevaluationhistoryModel
|
from core.apps.evaluation.models import (
|
||||||
|
AutoevaluationhistoryModel,
|
||||||
|
MechanicAutoevaluationhistoryModel,
|
||||||
|
QuickevaluationhistoryModel,
|
||||||
|
)
|
||||||
from core.apps.evaluation.serializers import history as serializers
|
from core.apps.evaluation.serializers import history as serializers
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +77,56 @@ class AutoEvaluationHistoryView(BaseViewSetMixin, ReadOnlyModelViewSet):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
tags=["MechanicAutoEvaluationHistory"],
|
||||||
|
parameters=[
|
||||||
|
OpenApiParameter("mechanic_auto_evaluation", int, description="MechanicAutoEvaluation ID bo'yicha filter"),
|
||||||
|
OpenApiParameter("event_type", str, description="Event turi bo'yicha filter"),
|
||||||
|
OpenApiParameter("created_from", str, description="Boshlanish sanasi (ISO 8601)"),
|
||||||
|
OpenApiParameter("created_to", str, description="Tugash sanasi (ISO 8601)"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
class MechanicAutoEvaluationHistoryView(BaseViewSetMixin, ReadOnlyModelViewSet):
|
||||||
|
queryset = MechanicAutoevaluationhistoryModel.objects.only(
|
||||||
|
"id", "mechanic_auto_evaluation_id", "event_type",
|
||||||
|
"actor_id", "actor_full_name", "actor_role",
|
||||||
|
"meta", "created_at",
|
||||||
|
)
|
||||||
|
serializer_class = serializers.ListMechanicAutoevaluationhistorySerializer
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
pagination_class = None
|
||||||
|
|
||||||
|
filter_backends = [DjangoFilterBackend, OrderingFilter]
|
||||||
|
filterset_class = MechanicAutoevaluationhistoryFilter
|
||||||
|
ordering_fields = [
|
||||||
|
"id",
|
||||||
|
"event_type",
|
||||||
|
"event_type_display",
|
||||||
|
"actor",
|
||||||
|
"meta",
|
||||||
|
"created_at",
|
||||||
|
]
|
||||||
|
ordering = ["created_at"]
|
||||||
|
|
||||||
|
action_permission_classes = {}
|
||||||
|
action_serializer_class = {
|
||||||
|
"list": serializers.ListMechanicAutoevaluationhistorySerializer,
|
||||||
|
"retrieve": serializers.RetrieveMechanicAutoevaluationhistorySerializer,
|
||||||
|
"create": serializers.CreateMechanicAutoevaluationhistorySerializer,
|
||||||
|
}
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
|
results = list(queryset)
|
||||||
|
serializer = self.get_serializer(results, many=True)
|
||||||
|
return Response({
|
||||||
|
"count": len(results),
|
||||||
|
"next": None,
|
||||||
|
"previous": None,
|
||||||
|
"results": serializer.data,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
tags=["QuickEvaluationHistory"],
|
tags=["QuickEvaluationHistory"],
|
||||||
parameters=[
|
parameters=[
|
||||||
|
|||||||
198
core/apps/evaluation/views/mechanic_auto.py
Normal file
198
core/apps/evaluation/views/mechanic_auto.py
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
from django.db.models import Q
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django_core.mixins import BaseViewSetMixin
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from drf_spectacular.utils import extend_schema, OpenApiParameter
|
||||||
|
from rest_framework import generics
|
||||||
|
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
|
from rest_framework.generics import GenericAPIView, ListAPIView
|
||||||
|
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from core.apps.accounts.permissions import IsAdminRole
|
||||||
|
from core.apps.accounts.serializers.user import UserSerializer
|
||||||
|
from core.apps.evaluation.filters.mechanic_auto import MechanicAutoevaluationFilter
|
||||||
|
from core.apps.evaluation.models import MechanicAutoEvaluationModel
|
||||||
|
from core.apps.evaluation.serializers.auto.MechanicAutoEvaluation import (
|
||||||
|
ListMechanicAutoevaluationSerializer,
|
||||||
|
RetrieveMechanicAutoevaluationSerializer,
|
||||||
|
CreateMechanicAutoevaluationSerializer,
|
||||||
|
UpdateMechanicAutoevaluationSerializer,
|
||||||
|
MechanicAutoEvaluationAppraisersSerializer,
|
||||||
|
MechanicAutoEvaluationModelSerializer,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationView(BaseViewSetMixin, ModelViewSet):
|
||||||
|
queryset = MechanicAutoEvaluationModel.objects.select_related(
|
||||||
|
"valuation",
|
||||||
|
"valuation__customer",
|
||||||
|
"vehicle",
|
||||||
|
).filter(is_archived=False)
|
||||||
|
serializer_class = ListMechanicAutoevaluationSerializer
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
|
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
|
||||||
|
filterset_class = MechanicAutoevaluationFilter
|
||||||
|
search_fields = [
|
||||||
|
"registration_number",
|
||||||
|
"car_model",
|
||||||
|
"car_brand",
|
||||||
|
"car_number",
|
||||||
|
]
|
||||||
|
ordering_fields = [
|
||||||
|
"id",
|
||||||
|
"contract_date",
|
||||||
|
"object_inspection_date",
|
||||||
|
"object_owner_individual_person_passport_num",
|
||||||
|
"object_owner_type",
|
||||||
|
"object_owner_individual_person_f_name",
|
||||||
|
"object_owner_individual_person_l_name",
|
||||||
|
"object_owner_individual_person_p_name",
|
||||||
|
"object_owner_legal_entity",
|
||||||
|
"object_owner_legal_inn",
|
||||||
|
"tex_passport_serie_num",
|
||||||
|
"rating_goal",
|
||||||
|
"registration_number",
|
||||||
|
"object_type",
|
||||||
|
"object_type_display",
|
||||||
|
"car_brand",
|
||||||
|
"car_model",
|
||||||
|
"car_number",
|
||||||
|
"manufacture_year",
|
||||||
|
"car_color",
|
||||||
|
"status",
|
||||||
|
"status_display",
|
||||||
|
"created_at",
|
||||||
|
"value_determined",
|
||||||
|
"rate_type",
|
||||||
|
]
|
||||||
|
ordering = ["-created_at"]
|
||||||
|
|
||||||
|
action_permission_classes = {}
|
||||||
|
action_serializer_class = {
|
||||||
|
"list": ListMechanicAutoevaluationSerializer,
|
||||||
|
"retrieve": RetrieveMechanicAutoevaluationSerializer,
|
||||||
|
"create": CreateMechanicAutoevaluationSerializer,
|
||||||
|
"update": UpdateMechanicAutoevaluationSerializer,
|
||||||
|
"partial_update": UpdateMechanicAutoevaluationSerializer,
|
||||||
|
}
|
||||||
|
|
||||||
|
def serializer_context(self):
|
||||||
|
return self.serializer_class(context={'request': self.request})
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationSetAppraisersView(GenericAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
queryset = MechanicAutoEvaluationModel.objects.all()
|
||||||
|
serializer_class = MechanicAutoEvaluationAppraisersSerializer
|
||||||
|
|
||||||
|
def post(self, request, id):
|
||||||
|
try:
|
||||||
|
evaluation = get_object_or_404(MechanicAutoEvaluationModel, id=id)
|
||||||
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
users = serializer.validated_data.get("users")
|
||||||
|
evaluation.appraisers.set(users)
|
||||||
|
evaluation.save()
|
||||||
|
return Response({"success": True, "data": "Foydalanuvchilar muvaffaqiyatli qo'shildi"})
|
||||||
|
except Exception as e:
|
||||||
|
return Response({"error": str(e)}, status=500)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationRemoveAppraisersView(GenericAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
queryset = MechanicAutoEvaluationModel.objects.all()
|
||||||
|
serializer_class = MechanicAutoEvaluationAppraisersSerializer
|
||||||
|
|
||||||
|
def post(self, request, id):
|
||||||
|
try:
|
||||||
|
evaluation = get_object_or_404(MechanicAutoEvaluationModel, id=id)
|
||||||
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
users = serializer.validated_data.get("users")
|
||||||
|
evaluation.appraisers.remove(*users)
|
||||||
|
evaluation.save()
|
||||||
|
return Response({"success": True, "data": "Foydalanuvchilar muvaffaqiyatli o'chirildi"})
|
||||||
|
except Exception as e:
|
||||||
|
return Response({"error": str(e)}, status=500)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationListAppraisersView(GenericAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
queryset = MechanicAutoEvaluationModel.objects.all()
|
||||||
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
parameters=[
|
||||||
|
OpenApiParameter(
|
||||||
|
name="search",
|
||||||
|
type=str,
|
||||||
|
description="Search query",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def get(self, request, id):
|
||||||
|
try:
|
||||||
|
search_query = request.query_params.get("search", "")
|
||||||
|
evaluation = get_object_or_404(MechanicAutoEvaluationModel, id=id)
|
||||||
|
query = evaluation.appraisers.all()
|
||||||
|
if search_query:
|
||||||
|
query = query.filter(
|
||||||
|
Q(phone__icontains=search_query) |
|
||||||
|
Q(first_name__icontains=search_query) |
|
||||||
|
Q(last_name__icontains=search_query)
|
||||||
|
)
|
||||||
|
page = self.paginate_queryset(query)
|
||||||
|
serializer = self.serializer_class(page, many=True)
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
except Exception as e:
|
||||||
|
return Response({"error": str(e)}, status=500)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationArchivedListAPIView(ListAPIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
serializer_class = ListMechanicAutoevaluationSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return MechanicAutoEvaluationModel.objects.filter(is_archived=True)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class MechanicAutoEvaluationArchiveAPIView(APIView):
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def post(self, request, pk):
|
||||||
|
evaluation = get_object_or_404(MechanicAutoEvaluationModel, pk=pk)
|
||||||
|
evaluation.is_archived = request.data["is_archived"]
|
||||||
|
evaluation.save()
|
||||||
|
return Response(
|
||||||
|
{
|
||||||
|
"success": True,
|
||||||
|
"status": evaluation.status,
|
||||||
|
"id": evaluation.pk
|
||||||
|
},
|
||||||
|
status=200
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["MechanicAutoEvaluation"])
|
||||||
|
class AdminMechanicEvaluationsAPIView(generics.GenericAPIView):
|
||||||
|
permission_classes = [IsAuthenticated, IsAdminRole]
|
||||||
|
queryset = MechanicAutoEvaluationModel.objects.all()
|
||||||
|
serializer_class = MechanicAutoEvaluationModelSerializer
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
evaluations = MechanicAutoEvaluationModel.objects.filter(
|
||||||
|
created_by=self.request.user
|
||||||
|
).distinct()
|
||||||
|
serializer = MechanicAutoEvaluationModelSerializer(evaluations, many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
61
task.txt
Normal file
61
task.txt
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
Odatiy avto baholash api'larini kopiyasi kerak. Qo'lda baholash uchun
|
||||||
|
|
||||||
|
[SIFAT-91] task bajarilib bo’linganidan so’ng ushbu taskni boshlang
|
||||||
|
|
||||||
|
Qo’lda baholash degani narxlar va hujjatlarni xodimlarni o’zlari aniqlab kiritadi. “Qo’lda baholash”ni odatiy “Avto baholash”dan farqli tomoni:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Hujjatlar Xodimlar tomonidan yuklanadi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Narx automatik xisoblanmaydi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mexanik baholash yaratilishida foydalanuvchi tanlanishi kerak
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Xozircha quyidagilarni copy qilib yasab bersangiz bo’lgani. Qolganini alohida task qilib kiritaman.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/ => /api/v1/mechanic-auto-evaluation/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/:id/ => /api/v1/mechanic-auto-evaluation/:id/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/appraisers/:id/list/ => /api/v1/mechanic-auto-evaluation/appraisers/:id/list/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/appraisers/:id/remove/ => /api/v1/mechanic-auto-evaluation/appraisers/:id/remove/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/appraisers/:id/set/ => /api/v1/mechanic-auto-evaluation/appraisers/:id/set/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation-history/ => /api/v1/mechanic-auto-evaluation-history/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/archive/list/ => /api/v1/mechanic-auto-evaluation/archive/list/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/api/v1/auto-evaluation/archive/:id/ => /api/v1/mechanic-auto-evaluation/archive/:id/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Endpointlar ko’rsatilganiday bo’lsin
|
||||||
Reference in New Issue
Block a user