25 Commits

Author SHA1 Message Date
Husanjonazamov
8409992afc test migrate 2026-03-10 13:04:20 +05:00
github-actions[bot]
6525a14ca6 🔄 Update image to 45 [CI SKIP] 2026-03-10 07:13:04 +00:00
5bb3dcd432 Merge pull request 'feat(auto-evaluation): to'liq CRUD API va 4 bosqichli forma qo'shildi' (#25) from feat/auto-evaluation-api into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m8s
Reviewed-on: #25
2026-03-10 07:11:18 +00:00
Husanjonazamov
5c2fe032d0 feat(auto-evaluation): to'liq CRUD API va 4 bosqichli forma qo'shildi
- 10 ta yangi choice klass qo'shildi: ObjectOwnerType, PropertyRights,
  FormOwnership, LocationHighways, LocationConvenience, AutoCarType, AutoCarWheel
- AutoEvaluationModel ga ~30 ta yangi field qo'shildi (4 bosqich):
  1-bosqich: ro'yxatga olish raqami, sanalar, ob'ekt turi
  2-bosqich: egasi ma'lumotlari (jismoniy/yuridik), mulk huquqi, egalik shakli
  3-bosqich: manzil (viloyat, tuman, shahar, mahalla, ko'cha, uy)
  4-bosqich: avtomobil (tex passport, marka, model, raqam, rang, dvigatel)
- CreateSerializer ga validatsiya qo'shildi:
  passport formati (AA 1234567), tex passport formati (AAA 1234567),
  egasi turiga qarab majburiy fieldlar (jismoniy yoki yuridik)
- View ReadOnlyModelViewSet dan ModelViewSet ga o'zgartirildi
- Admin 4 bosqichli fieldset bilan yangilandi
- Yangi filterlar: object_owner_type, property_rights, form_ownership
- VehicleModel fieldlari FK → ReferenceitemModel ga o'tkazildi
- Migratsiyalar: 0015, 0016, 0017
2026-03-10 12:10:28 +05:00
github-actions[bot]
b3581233c1 🔄 Update image to 44 [CI SKIP] 2026-03-09 11:22:03 +00:00
8d30162e87 Merge pull request 'fix test error' (#24) from fix/reference into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m7s
Reviewed-on: #24
2026-03-09 11:20:19 +00:00
Husanjonazamov
44f53649cd fix test error 2026-03-09 16:19:53 +05:00
460e3158b8 Merge pull request 'feat: add ReferenceItem model and update QuickEvaluation FKs' (#23) from feat/quick-evaluation-create-api into main
Some checks failed
Deploy to Production / build-and-deploy (push) Failing after 1m24s
Reviewed-on: #23
2026-03-09 11:04:38 +00:00
Husanjonazamov
3798037240 feat: add ReferenceItem model and update QuickEvaluation FKs
- Create ReferenceitemModel with type, name, parent (self FK), order, is_active fields
- Add ReferenceType choices: brand, marka, color, fuel_type, body_type, car_position, state_car
- Implement ReferenceItem API (list, retrieve) with filter by type/parent/is_active, search, ordering
- Add ReferenceItem admin with list_filter, search, inline editing
- Change QuickEvaluation FK fields from shared.OptionsModel to evaluation.ReferenceitemModel
- Update serializers and views to use .name instead of .key
- Add ReferenceItem to unfold admin navigation
2026-03-09 16:04:15 +05:00
github-actions[bot]
fd2ecd953a 🔄 Update image to 42 [CI SKIP] 2026-03-09 08:32:20 +00:00
9d405330c6 Merge pull request 'feat: add search, filter, sort and pagination to QuickEvaluation list API' (#22) from feat/quick-evaluation-list-api into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m50s
Reviewed-on: #22
2026-03-09 08:30:49 +00:00
Husanjonazamov
8feee78ce4 feat: add search, filter, sort and pagination to QuickEvaluation list API 2026-03-09 13:21:55 +05:00
github-actions[bot]
1e67a9f86e 🔄 Update image to 41 [CI SKIP] 2026-03-09 07:30:29 +00:00
9c176674f9 Merge pull request 'tezkor avto baholanganlarni id bo'yicha olish uchun api qoshilfi' (#21) from feat/quick-evaluation-detail-api into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m53s
Reviewed-on: #21
2026-03-09 07:28:57 +00:00
Husanjonazamov
04d5b92ac5 tezkor avto baholanganlarni id bo'yicha olish uchun api qoshilfi 2026-03-09 12:26:29 +05:00
github-actions[bot]
50e085fcfd 🔄 Update image to 40 [CI SKIP] 2026-03-05 09:58:13 +00:00
13ba9dcae4 Merge pull request 'log file va test ad file togirilafi' (#20) from fix/cicd-stockv2 into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m8s
Reviewed-on: #20
2026-03-05 09:56:27 +00:00
Husanjonazamov
3707e10ccf log file va test ad file togirilafi 2026-03-05 14:56:06 +05:00
github-actions[bot]
1d275b9907 🔄 Update image to 39 [CI SKIP] 2026-03-02 07:36:37 +00:00
1ccee92417 Merge pull request 'hamma modellarda get serizlizers uchun fiedl qoshilfi' (#19) from feat/get-serializers into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 5m0s
Reviewed-on: #19
2026-03-02 07:31:58 +00:00
Husanjonazamov
1a90803527 hamma modellarda get serizlizers uchun fiedl qoshilfi 2026-03-02 12:31:16 +05:00
github-actions[bot]
8d4eea1dfa 🔄 Update image to 38 [CI SKIP] 2026-02-23 12:43:23 +00:00
cabd159774 Merge pull request 'serach tigurkladfi' (#18) from feat/ad-forms into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m22s
Reviewed-on: #18
2026-02-23 12:41:22 +00:00
Husanjonazamov
e51dd1f952 serach tigurkladfi 2026-02-23 17:40:50 +05:00
github-actions[bot]
a92a2599c7 🔄 Update image to 37 [CI SKIP] 2026-02-18 13:19:30 +00:00
80 changed files with 2448 additions and 216 deletions

View File

@@ -73,3 +73,6 @@ STORAGE_BUCKET_STATIC=name
STORAGE_PATH=127.0.0.1:8081/bucket/
STORAGE_PROTOCOL=http:
# Celery configs

2
.gitignore vendored
View File

@@ -2,7 +2,7 @@ node_modules
# OS ignores
*.DS_Store
#sa
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

114
API_ENDPOINTS.md Normal file
View File

@@ -0,0 +1,114 @@
# SifatBaho — GET API Endpoints
> Barcha endpointlar hozirda `AllowAny` permission bilan ishlaydi.
> Token yuborish shart emas (hozircha).
> Base URL: `http://localhost:8000/api/v1/`
---
## 🔐 Auth (Autentifikatsiya)
| # | URL | Method | Tavsif |
|---|-----|--------|--------|
| 1 | `api/v1/auth/token/` | POST | Login — access va refresh token olish |
| 2 | `api/v1/auth/token/refresh/` | POST | Access tokenni yangilash |
| 3 | `api/v1/auth/token/verify/` | POST | Tokenni tekshirish |
---
## 👤 Buyurtmachilar
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 1 | `api/v1/customer/` | GET | ❌ | Barcha buyurtmachilar ro'yxati (ism, INN, JSHSHIR) |
| 2 | `api/v1/customer/{id}/` | GET | ❌ | Bitta buyurtmachining to'liq ma'lumotlari (passport, manzil, bank) |
| 3 | `api/v1/property-owner/` | GET | ❌ | Barcha mulk egalari ro'yxati |
| 4 | `api/v1/property-owner/{id}/` | GET | ❌ | Bitta mulk egasining to'liq ma'lumotlari |
---
## 📋 Arizalar (Valuation)
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 5 | `api/v1/valuation/` | GET | ❌ | Barcha arizalar ro'yxati (raqam, tur, status, narx) |
| 6 | `api/v1/valuation/{id}/` | GET | ❌ | Bitta arizaning to'liq ma'lumotlari (buyurtmachi, baholovchi, narxlar) |
---
## 🚗 Transport vositalari
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 7 | `api/v1/vehicle/` | GET | ❌ | Barcha transportlar ro'yxati (marka, model, raqam, rang) |
| 8 | `api/v1/vehicle/{id}/` | GET | ❌ | Bitta transportning to'liq ma'lumotlari (VIN, tex passport, yurgan km) |
---
## 🔧 Avto baholash
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 9 | `api/v1/auto-evaluation/` | GET | ❌ | Barcha avto baholashlar (ariza + moshina bog'lanishi) |
| 10 | `api/v1/auto-evaluation/{id}/` | GET | ❌ | Bitta avto baholash detali (ariza va moshina to'liq) |
---
## 🏠 Ko'chmas mulk baholash
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 11 | `api/v1/real-estate-evaluation/` | GET | ❌ | Barcha ko'chmas mulk baholashlar (tur, manzil, maydon) |
| 12 | `api/v1/real-estate-evaluation/{id}/` | GET | ❌ | Bitta ko'chmas mulk detali (kadastr, qavat, xonalar) |
---
## 📦 Ko'char mulk baholash
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 13 | `api/v1/movable-property-evaluation/` | GET | ❌ | Barcha ko'char mulk baholashlar (nomi, kategoriya, soni) |
| 14 | `api/v1/movable-property-evaluation/{id}/` | GET | ❌ | Bitta ko'char mulk detali (seriya raqami, holat) |
---
## ⚡ Tezkor baholash
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 15 | `api/v1/quick-evaluation/` | GET | ❌ | Barcha tezkor baholashlar (marka, model, taxminiy narx) |
| 16 | `api/v1/quick-evaluation/{id}/` | GET | ❌ | Bitta tezkor baholash detali (VIN, yoqilg'i turi, holat) |
---
## 📄 Hisobotlar
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 17 | `api/v1/evaluation-report/` | GET | ❌ | Barcha hisobotlar ro'yxati (raqam, baholovchi, yakuniy narx) |
| 18 | `api/v1/evaluation-report/{id}/` | GET | ❌ | Bitta hisobot detali (xulosa matni, PDF fayl) |
---
## 📎 Ariza hujjatlari
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 19 | `api/v1/valuation-document/` | GET | ❌ | Barcha hujjatlar ro'yxati (turi, sarlavha, fayl) |
| 20 | `api/v1/valuation-document/{id}/` | GET | ❌ | Bitta hujjat detali (tavsif, kim yuklagan) |
---
## 💳 To'lovlar
| # | URL | Method | Token | Tavsif |
|---|-----|--------|-------|--------|
| 21 | `api/v1/payment/` | GET | ❌ | Barcha to'lovlar ro'yxati (summa, usul, status) |
| 22 | `api/v1/payment/{id}/` | GET | ❌ | Bitta to'lov detali (tranzaksiya ID, izoh) |
---
**Jami: 22 ta GET endpoint** (11 ta List + 11 ta Detail)
> ⚠️ Hozir barcha endpointlar `AllowAny` — token kerak emas.
> Keyinchalik `IsAuthenticated` ga o'zgartiriladi.

View File

@@ -107,4 +107,15 @@ PAGES = [
},
],
},
{
"title": _("Ma'lumotnomalari"),
"separator": True,
"items": [
{
"title": _("Ma'lumotnomalar"),
"icon": "category",
"link": reverse_lazy("admin:evaluation_referenceitemmodel_changelist"),
},
],
},
]

View File

@@ -13,7 +13,7 @@ from config.env import env
def home(request):
return HttpResponse("OK: #7b05f1f99ef8f95bf6752b1f4c29c9a02b573975")
return HttpResponse("OK: #5bb3dcd432ba0c045e6f2ef91c23bd4a16a1d256")
urlpatterns = [

View File

@@ -14,5 +14,6 @@ admin.site.unregister(db_models.Group)
admin.site.register(db_models.Group, user.GroupAdmin)
admin.site.register(db_models.Permission, user.PermissionAdmin)
admin.site.register(get_user_model(), user.CustomUserAdmin)
admin.site.register(SmsConfirm, SmsConfirmAdmin)

View File

@@ -15,6 +15,7 @@ class CustomUserAdmin(admin.UserAdmin, ModelAdmin):
"phone",
"role",
)
search_fields = ("phone", "first_name", "last_name", "username")
autocomplete_fields = ["groups", "user_permissions"]
fieldsets = ((None, {"fields": ("phone",)}),) + (
(None, {"fields": ("username", "password")}),
@@ -37,7 +38,7 @@ class CustomUserAdmin(admin.UserAdmin, ModelAdmin):
class PermissionAdmin(ModelAdmin):
list_display = ("name",)
list_display = ("name",)
search_fields = ("name",)

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -8,22 +8,66 @@ from core.apps.evaluation.models import AutoEvaluationModel
class AutoEvaluationAdmin(ModelAdmin):
list_display = (
"id",
"valuation",
"vehicle",
"registration_number",
"object_type",
"car_brand",
"car_model",
"car_number",
"status",
"created_at",
)
list_filter = ("status", "object_type", "rate_type", "value_determined", "object_owner_type")
search_fields = (
"valuation__conclusion_number",
"vehicle__brand",
"vehicle__model",
"vehicle__license_plate",
"registration_number",
"car_brand",
"car_model",
"car_number",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation", "vehicle")
autocomplete_fields = ("valuation", "vehicle")
fieldsets = (
("Bog'lanishlar", {
"classes": ("collapse",),
"fields": ("valuation", "vehicle"),
}),
("Step 1 — Umumiy ma'lumotlar", {
"fields": (
"registration_number",
("contract_date", "object_inspection_date"),
("rate_date", "rate_report_date"),
"rate_object_name",
"object_type",
"status",
),
}),
("Step 2 — Shaxs ma'lumotlari", {
"fields": (
"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"),
("property_rights", "form_ownership"),
("value_determined", "rate_type"),
),
}),
("Step 3 — Manzil ma'lumotlari", {
"fields": (
("object_location_province", "object_location_district"),
("object_location_city", "object_location_neighborhood"),
("object_location_street", "object_location_home"),
("object_location_highways", "object_location_covenience"),
),
}),
("Step 4 — Avtomobil ma'lumotlari", {
"fields": (
"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"),
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),

View File

@@ -21,7 +21,7 @@ class ValuationDocumentAdmin(ModelAdmin):
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation", "uploaded_by")
autocomplete_fields = ("valuation", "uploaded_by")
fieldsets = (
("Hujjat", {
"fields": (

View File

@@ -26,7 +26,7 @@ class MovablePropertyEvaluationAdmin(ModelAdmin):
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation",)
autocomplete_fields = ("valuation",)
fieldsets = (
("Ariza", {
"fields": ("valuation",),

View File

@@ -10,50 +10,55 @@ class QuickEvaluationAdmin(ModelAdmin):
"id",
"created_by",
"brand",
"model",
"license_plate",
"manufacture_year",
"condition",
"marka",
"car_number",
"car_manufactured_date",
"estimated_price",
"status",
"car_type",
"state_car",
"created_at",
)
list_filter = (
"fuel_type",
"body_type",
"condition",
"status",
"car_type",
)
search_fields = (
"brand",
"model",
"license_plate",
"car_number",
"vin_number",
"engine_number",
"tech_passport_number",
"tex_passport_serie_num",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("created_by",)
autocomplete_fields = ("created_by",)
fieldsets = (
("Foydalanuvchi", {
"fields": ("created_by",),
}),
("Tex passport", {
"fields": (
"tex_passport_serie_num",
("tech_passport_issued_date", "tech_passport_issued_place"),
"tex_passport_file",
),
}),
("Transport ma'lumotlari", {
"fields": (
"tech_passport_number",
"license_plate",
("brand", "model"),
("manufacture_year", "color"),
"car_number",
("brand", "marka"),
("car_manufactured_date", "color"),
("vin_number", "engine_number"),
"mileage",
("distance_covered", "car_position"),
),
}),
("Texnik holat", {
"fields": (
("fuel_type", "body_type"),
"condition",
("car_type", "state_car"),
),
}),
("Natija", {
"fields": ("estimated_price",),
"fields": ("estimated_price", "status"),
}),
("Tizim", {
"classes": ("collapse",),

View File

@@ -27,7 +27,7 @@ class RealEstateEvaluationAdmin(ModelAdmin):
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation",)
autocomplete_fields = ("valuation",)
fieldsets = (
("Ariza", {
"fields": ("valuation",),

View File

@@ -0,0 +1,18 @@
from django.contrib import admin
from unfold.admin import ModelAdmin
from core.apps.evaluation.models import ReferenceitemModel
@admin.register(ReferenceitemModel)
class ReferenceitemAdmin(ModelAdmin):
list_display = ("id", "type", "name", "parent", "order", "is_active")
list_filter = ("type", "is_active")
search_fields = ("name",)
list_editable = ("order", "is_active")
autocomplete_fields = ("parent",)
fieldsets = (
(None, {
"fields": ("type", "name", "parent", "order", "is_active"),
}),
)

View File

@@ -24,7 +24,7 @@ class EvaluationReportAdmin(ModelAdmin):
"conclusion_text",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation", "evaluator")
autocomplete_fields = ("valuation", "evaluator")
fieldsets = (
("Hisobot", {
"fields": (

View File

@@ -33,7 +33,7 @@ class ValuationAdmin(ModelAdmin):
"customer__inn",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("customer", "property_owner", "created_by", "assigned_to")
autocomplete_fields = ("customer", "property_owner", "created_by", "assigned_to")
fieldsets = (
("Asosiy ma'lumotlar", {
"fields": (

View File

@@ -18,20 +18,19 @@ class VehicleAdmin(ModelAdmin):
"mileage",
)
list_filter = (
"fuel_type",
"body_type",
"condition",
"manufacture_year",
)
search_fields = (
"brand",
"model",
"brand__name",
"model__name",
"license_plate",
"vin_number",
"engine_number",
"tech_passport_number",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("brand", "model", "color", "fuel_type", "body_type", "position")
fieldsets = (
("Texnik passport", {
"fields": (

View File

@@ -0,0 +1,70 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class AutoObjectType(models.TextChoices):
LIGHTWEIGHT_AUTO = "lightweight_auto", _("Yengil automobil")
TRUCK_CAR = "truck_car", _("Yuk automobil")
SPECIAL_TECH = "special_tech", _("Maxsus texnika")
class AutoEvaluationStatus(models.TextChoices):
CREATED = "yaratildi", _("Yaratildi")
EVALUATOR_ASSIGNED = "baxolovchi_biriktirildi", _("Baholovchi biriktirildi")
EVALUATED = "baxolandi", _("Baholandi")
REJECTED = "rad_etildi", _("Rad etildi")
APPROVED = "tasdiqlandi", _("Tasdiqlandi")
class ObjectOwnerType(models.IntegerChoices):
INDIVIDUAL = 1, _("Jismoniy shaxs")
LEGAL = 2, _("Yuridik shaxs")
class PropertyRights(models.IntegerChoices):
PERMANENT_OWNERSHIP = 1, _("Doimiy egalik")
PERMANENT_USE = 2, _("Doimiy foydalanish")
TEMPORARY_USE = 3, _("Vaqtinchalik foydalanish")
TERM_LEASE = 4, _("Muddatli ijara")
LIFETIME_INHERITANCE = 5, _("Umrbod meros qilib olish")
class FormOwnership(models.IntegerChoices):
PRIVATE = 1, _("Xususiy")
STATE = 2, _("Davlat")
JSC = 3, _("AJ")
LLC = 4, _("MCHJ")
OTHER = 5, _("Boshqa")
class ValueDetermined(models.IntegerChoices):
MARKET_VALUE = 1, _("Bozor qiymati")
TAX_PURPOSE = 2, _("Soliq maqsadlari uchun")
LIQUIDATION_VALUE = 3, _("Tugatish qiymati")
UTILIZATION_VALUE = 4, _("Utilizatsiya qiymati")
class RateType(models.IntegerChoices):
CREDIT_COLLATERAL = 1, _("Kredit ta'minoti sifatida garovga qo'yish")
SALE_PURPOSE = 2, _("Sotish maqsadida bozor qiymatini aniqlash")
TAX_PURPOSE = 3, _("Soliqqa tortish maqsadida")
OTHER = 4, _("Boshqa")
class LocationHighways(models.IntegerChoices):
CENTER = 1, _("Tuman/Shahar markazi")
FAR_FROM_CENTER = 2, _("Tuman/shahar markazidan uzoqda")
class LocationConvenience(models.IntegerChoices):
POPULATED_AREA = 1, _("Aholi gavjum hudud")
MARKET_AREA = 2, _("Bozor hududi")
class AutoCarType(models.IntegerChoices):
HATCHBACK = 1, _("Xetchbek")
UNIVERSAL = 2, _("Universal")
class AutoCarWheel(models.IntegerChoices):
FOUR_BY_FOUR = 1, _("4x4")

View File

@@ -0,0 +1,17 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class QuickEvaluationStatus(models.TextChoices):
CREATED = "created", _("Created")
EVALUATOR_ASSIGNED = "evaluator_assigned", _("Evaluator assigned")
EVALUATED = "evaluated", _("Evaluated")
REJECTED = "rejected", _("Rejected")
APPROVED = "approved", _("Approved")
class CarType(models.TextChoices):
LIGHTWEIGHT = "lightweight", _("Lightweight")
TRUCK = "truck", _("Truck")
BUS = "bus", _("Bus")
MOTO = "moto", _("Moto")

View File

@@ -0,0 +1,12 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class ReferenceType(models.TextChoices):
BRAND = "brand", _("Brand")
MARKA = "marka", _("Marka")
COLOR = "color", _("Color")
FUEL_TYPE = "fuel_type", _("Fuel type")
BODY_TYPE = "body_type", _("Body type")
CAR_POSITION = "car_position", _("Car position")
STATE_CAR = "state_car", _("Car state")

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -1,13 +1,45 @@
# from django_filters import rest_framework as filters
from django_filters import rest_framework as filters
# from core.apps.evaluation.models import AutoEvaluationModel
from core.apps.evaluation.models import AutoEvaluationModel
# class AutoevaluationFilter(filters.FilterSet):
# # name = filters.CharFilter(field_name="name", lookup_expr="icontains")
class AutoevaluationFilter(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")
property_rights = filters.NumberFilter(field_name="property_rights", lookup_expr="exact")
form_ownership = filters.NumberFilter(field_name="form_ownership", lookup_expr="exact")
object_location_province = filters.CharFilter(
field_name="object_location_province", lookup_expr="icontains"
)
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")
# class Meta:
# model = AutoEvaluationModel
# fields = [
# "name",
# ]
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 = AutoEvaluationModel
fields = [
"status",
"object_type",
"object_owner_type",
"rate_type",
"value_determined",
"property_rights",
"form_ownership",
"object_location_province",
"client",
"created_from",
"created_to",
"rate_date_from",
"rate_date_to",
]

View File

@@ -8,6 +8,4 @@ class ValuationdocumentFilter(filters.FilterSet):
class Meta:
model = ValuationDocumentModel
fields = [
"name",
]
fields = []

View File

@@ -4,10 +4,28 @@ from core.apps.evaluation.models import QuickEvaluationModel
class QuickevaluationFilter(filters.FilterSet):
# name = filters.CharFilter(field_name="name", lookup_expr="icontains")
status = filters.CharFilter(method="filter_status")
car_type = filters.CharFilter(field_name="car_type", lookup_expr="exact")
state_car = filters.NumberFilter(field_name="state_car", 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")
year_from = filters.NumberFilter(field_name="car_manufactured_date", lookup_expr="gte")
year_to = filters.NumberFilter(field_name="car_manufactured_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 = QuickEvaluationModel
fields = [
"name",
"status",
"car_type",
"state_car",
"created_from",
"created_to",
"year_from",
"year_to",
]

View File

@@ -8,6 +8,4 @@ class RealestateevaluationFilter(filters.FilterSet):
class Meta:
model = RealEstateEvaluationModel
fields = [
"name",
]
fields = []

View File

@@ -0,0 +1,17 @@
from django_filters import rest_framework as filters
from core.apps.evaluation.models import ReferenceitemModel
class ReferenceitemFilter(filters.FilterSet):
type = filters.CharFilter(field_name="type", lookup_expr="exact")
parent = filters.NumberFilter(field_name="parent", lookup_expr="exact")
is_active = filters.BooleanFilter(field_name="is_active")
class Meta:
model = ReferenceitemModel
fields = [
"type",
"parent",
"is_active",
]

View File

@@ -8,6 +8,4 @@ class EvaluationreportFilter(filters.FilterSet):
class Meta:
model = EvaluationReportModel
fields = [
"name",
]
fields = []

View File

@@ -8,6 +8,4 @@ class ValuationFilter(filters.FilterSet):
class Meta:
model = ValuationModel
fields = [
"name",
]
fields = []

View File

@@ -8,6 +8,4 @@ class VehicleFilter(filters.FilterSet):
class Meta:
model = VehicleModel
fields = [
"name",
]
fields = []

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1,10 @@
from django import forms
from core.apps.evaluation.models import ReferenceitemModel
class ReferenceitemForm(forms.ModelForm):
class Meta:
model = ReferenceitemModel
fields = "__all__"

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.2.7 on 2026-03-09 07:59
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0009_valuationdocumentmodel'),
]
operations = [
migrations.AddField(
model_name='quickevaluationmodel',
name='car_type',
field=models.CharField(blank=True, choices=[('lightweight', 'Yengil avtomobil'), ('yuk', 'Yuk mashinasi'), ('bus', 'Avtobus'), ('moto', 'Mototsikl')], max_length=50, null=True, verbose_name='car type'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='state_car',
field=models.CharField(blank=True, choices=[('yaxshi', 'Yaxshi'), ('qoniqarli', 'Qoniqarli'), ('yomon', 'Yomon')], max_length=50, null=True, verbose_name='car state'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='status',
field=models.CharField(choices=[('yaratildi', 'Yaratildi'), ('baxolovchi_biriktirildi', 'Baxolovchi biriktirildi'), ('baxolandi', 'Baxolandi'), ('rad_etildi', 'Rad etildi'), ('tasdiqlandi', 'Tasdiqlandi')], default='yaratildi', max_length=50, verbose_name='status'),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.2.7 on 2026-03-09 08:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0010_add_status_car_type_state_car_to_quick_evaluation'),
]
operations = [
migrations.AlterField(
model_name='quickevaluationmodel',
name='car_type',
field=models.CharField(blank=True, choices=[('lightweight', 'Lightweight'), ('truck', 'Truck'), ('bus', 'Bus'), ('moto', 'Moto')], max_length=50, null=True, verbose_name='car type'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='state_car',
field=models.CharField(blank=True, choices=[('good', 'Good'), ('satisfactory', 'Satisfactory'), ('bad', 'Bad')], max_length=50, null=True, verbose_name='car state'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='status',
field=models.CharField(choices=[('created', 'Created'), ('evaluator_assigned', 'Evaluator assigned'), ('evaluated', 'Evaluated'), ('rejected', 'Rejected'), ('approved', 'Approved')], default='created', max_length=50, verbose_name='status'),
),
]

View File

@@ -0,0 +1,109 @@
# Generated by Django 5.2.7 on 2026-03-09 09:57
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0011_update_choices_to_english'),
('shared', '0002_settingsmodel_created_at_settingsmodel_description_and_more'),
]
operations = [
migrations.RemoveField(
model_name='quickevaluationmodel',
name='condition',
),
migrations.RemoveField(
model_name='quickevaluationmodel',
name='license_plate',
),
migrations.RemoveField(
model_name='quickevaluationmodel',
name='manufacture_year',
),
migrations.RemoveField(
model_name='quickevaluationmodel',
name='mileage',
),
migrations.RemoveField(
model_name='quickevaluationmodel',
name='model',
),
migrations.RemoveField(
model_name='quickevaluationmodel',
name='tech_passport_number',
),
migrations.AddField(
model_name='quickevaluationmodel',
name='car_manufactured_date',
field=models.IntegerField(blank=True, null=True, verbose_name='manufacture year'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='car_number',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='car number'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='car_position',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_positions', to='shared.optionsmodel', verbose_name='car position'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='distance_covered',
field=models.IntegerField(blank=True, null=True, verbose_name='distance covered (km)'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='marka',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_markas', to='shared.optionsmodel', verbose_name='marka'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='tech_passport_issued_date',
field=models.DateField(blank=True, null=True, verbose_name='tech passport issued date'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='tech_passport_issued_place',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='tech passport issued place'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='tex_passport_file',
field=models.FileField(blank=True, null=True, upload_to='quick_evaluation/tech_passports/%Y/%m/', verbose_name='tech passport file'),
),
migrations.AddField(
model_name='quickevaluationmodel',
name='tex_passport_serie_num',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='tech passport series and number'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='body_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_body_types', to='shared.optionsmodel', verbose_name='body type'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='brand',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_brands', to='shared.optionsmodel', verbose_name='brand'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='color',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_colors', to='shared.optionsmodel', verbose_name='color'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='fuel_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_fuel_types', to='shared.optionsmodel', verbose_name='fuel type'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='state_car',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_states', to='shared.optionsmodel', verbose_name='car state'),
),
]

View File

@@ -0,0 +1,33 @@
# Generated by Django 5.2.7 on 2026-03-09 10:49
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0012_remove_quickevaluationmodel_condition_and_more'),
]
operations = [
migrations.CreateModel(
name='ReferenceitemModel',
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)),
('type', models.CharField(choices=[('brand', 'Brand'), ('marka', 'Marka'), ('color', 'Color'), ('fuel_type', 'Fuel type'), ('body_type', 'Body type'), ('car_position', 'Car position'), ('state_car', 'Car state')], max_length=50, verbose_name='type')),
('name', models.CharField(max_length=255, verbose_name='name')),
('order', models.IntegerField(default=0, verbose_name='order')),
('is_active', models.BooleanField(default=True, verbose_name='is active')),
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='evaluation.referenceitemmodel', verbose_name='parent')),
],
options={
'verbose_name': 'Reference Item',
'verbose_name_plural': 'Reference Items',
'db_table': 'ReferenceItem',
'ordering': ['type', 'order', 'name'],
},
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 5.2.7 on 2026-03-09 10:51
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0013_referenceitemmodel'),
]
operations = [
migrations.AlterField(
model_name='quickevaluationmodel',
name='body_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_body_types', to='evaluation.referenceitemmodel', verbose_name='body type'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='brand',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_brands', to='evaluation.referenceitemmodel', verbose_name='brand'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='car_position',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_positions', to='evaluation.referenceitemmodel', verbose_name='car position'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='color',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_colors', to='evaluation.referenceitemmodel', verbose_name='color'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='fuel_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_fuel_types', to='evaluation.referenceitemmodel', verbose_name='fuel type'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='marka',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_markas', to='evaluation.referenceitemmodel', verbose_name='marka'),
),
migrations.AlterField(
model_name='quickevaluationmodel',
name='state_car',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='quick_eval_states', to='evaluation.referenceitemmodel', verbose_name='car state'),
),
]

View File

@@ -0,0 +1,108 @@
# Generated by Django 5.2.7 on 2026-03-09 12:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0014_alter_quickevaluationmodel_body_type_and_more'),
]
operations = [
migrations.AddField(
model_name='autoevaluationmodel',
name='contract_date',
field=models.DateField(blank=True, null=True, verbose_name='contract date'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='form_ownership',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='form of ownership'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_inspection_date',
field=models.DateField(blank=True, null=True, verbose_name='object inspection date'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_city',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object location city'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_district',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object location district'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_province',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object location province'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_type',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object owner type'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_type',
field=models.CharField(blank=True, choices=[('lightweight_auto', 'Lightweight Auto'), ('truck_car', 'Truck Car'), ('special_tech', 'Special Tech')], max_length=50, null=True, verbose_name='object type'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='property_rights',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='property rights'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='rate_date',
field=models.DateField(blank=True, null=True, verbose_name='rate date'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='rate_object_name',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='rate object name'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='rate_report_date',
field=models.DateField(blank=True, null=True, verbose_name='rate report date'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='rate_type',
field=models.IntegerField(blank=True, choices=[(1, '1-tur'), (2, '2-tur'), (3, '3-tur'), (4, '4-tur')], null=True, verbose_name='rate type'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='rating_goal',
field=models.CharField(blank=True, choices=[('sotuv', 'Sotuv'), ('kredit', 'Kredit'), ('sugurta', "Sug'urta"), ('boshqa', 'Boshqa')], max_length=50, null=True, verbose_name='rating goal'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='registration_number',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='registration number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='status',
field=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'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='tex_passport_gived_date',
field=models.DateField(blank=True, null=True, verbose_name='tech passport given date'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='tex_passport_serie_num',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='tech passport series and number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='value_determined',
field=models.IntegerField(blank=True, choices=[(1, '1-qiymat'), (2, '2-qiymat'), (3, '3-qiymat'), (4, '4-qiymat')], null=True, verbose_name='value determined'),
),
]

View File

@@ -0,0 +1,44 @@
# Generated by Django 5.2.7 on 2026-03-09 12:34
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0015_autoevaluationmodel_contract_date_and_more'),
]
operations = [
migrations.AlterField(
model_name='vehiclemodel',
name='body_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_body_types', to='evaluation.referenceitemmodel', verbose_name='body type'),
),
migrations.AlterField(
model_name='vehiclemodel',
name='brand',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_brands', to='evaluation.referenceitemmodel', verbose_name='brand'),
),
migrations.AlterField(
model_name='vehiclemodel',
name='color',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_colors', to='evaluation.referenceitemmodel', verbose_name='color'),
),
migrations.AlterField(
model_name='vehiclemodel',
name='fuel_type',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_fuel_types', to='evaluation.referenceitemmodel', verbose_name='fuel type'),
),
migrations.AlterField(
model_name='vehiclemodel',
name='model',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_models', to='evaluation.referenceitemmodel', verbose_name='model'),
),
migrations.AlterField(
model_name='vehiclemodel',
name='position',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='vehicle_positions', to='evaluation.referenceitemmodel', verbose_name='position'),
),
]

View File

@@ -0,0 +1,159 @@
# Generated by Django 5.2.7 on 2026-03-09 12:54
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0016_alter_vehiclemodel_body_type_and_more'),
]
operations = [
migrations.AddField(
model_name='autoevaluationmodel',
name='car_brand',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='car brand'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_color',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='car color'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_dvigatel_number',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='engine number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_model',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='car model'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_number',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='car number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_type',
field=models.IntegerField(blank=True, choices=[(1, 'Xetchbek'), (2, 'Universal')], null=True, verbose_name='car type'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='car_wheel',
field=models.IntegerField(blank=True, choices=[(1, '4x4')], null=True, verbose_name='car wheel'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='manufacture_year',
field=models.CharField(blank=True, max_length=10, null=True, verbose_name='manufacture year'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_covenience',
field=models.IntegerField(blank=True, choices=[(1, 'Aholi gavjum hudud'), (2, 'Bozor hududi')], null=True, verbose_name='location convenience'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_highways',
field=models.IntegerField(blank=True, choices=[(1, 'Tuman/Shahar markazi'), (2, 'Tuman/shahar markazidan uzoqda')], null=True, verbose_name='location highways'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_home',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='object location home'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_neighborhood',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object location neighborhood'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_location_street',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='object location street'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_individual_person_f_name',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='owner first name'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_individual_person_l_name',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='owner last name'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_individual_person_p_name',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='owner patronymic'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_individual_person_passport_num',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='owner passport number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_legal_entity',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='legal entity name'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='object_owner_legal_inn',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='legal entity INN'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='tex_passport_gived_location',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='tech passport given location'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='form_ownership',
field=models.IntegerField(blank=True, choices=[(1, 'Xususiy'), (2, 'Davlat'), (3, 'AJ'), (4, 'MCHJ'), (5, 'Boshqa')], null=True, verbose_name='form of ownership'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='object_owner_type',
field=models.IntegerField(blank=True, choices=[(1, 'Jismoniy shaxs'), (2, 'Yuridik shaxs')], null=True, verbose_name='object owner type'),
),
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')], max_length=50, null=True, verbose_name='object type'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='property_rights',
field=models.IntegerField(blank=True, choices=[(1, 'Doimiy egalik'), (2, 'Doimiy foydalanish'), (3, 'Vaqtinchalik foydalanish'), (4, 'Muddatli ijara'), (5, 'Umrbod meros qilib olish')], null=True, verbose_name='property rights'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='rate_type',
field=models.IntegerField(blank=True, choices=[(1, "Kredit ta'minoti sifatida garovga qo'yish"), (2, 'Sotish maqsadida bozor qiymatini aniqlash'), (3, 'Soliqqa tortish maqsadida'), (4, 'Boshqa')], null=True, verbose_name='rate type'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='rating_goal',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='rating goal'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='valuation',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='auto_detail', to='evaluation.valuationmodel', verbose_name='valuation'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='value_determined',
field=models.IntegerField(blank=True, choices=[(1, 'Bozor qiymati'), (2, 'Soliq maqsadlari uchun'), (3, 'Tugatish qiymati'), (4, 'Utilizatsiya qiymati')], null=True, verbose_name='value determined'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='vehicle',
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='evaluation', to='evaluation.vehiclemodel', verbose_name='vehicle'),
),
]

View File

@@ -0,0 +1,58 @@
# Generated by Django 5.2.7 on 2026-03-10 07:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0017_autoevaluationmodel_car_brand_and_more'),
]
operations = [
migrations.AddField(
model_name='autoevaluationmodel',
name='chassi',
field=models.IntegerField(blank=True, null=True, verbose_name='chassi'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='customer_inn_number',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='customer INN number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='location_lat',
field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True, verbose_name='location latitude'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='location_lng',
field=models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True, verbose_name='location longitude'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='need_delivering',
field=models.BooleanField(default=True, verbose_name='need delivering'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='owner_inn_number',
field=models.CharField(blank=True, max_length=20, null=True, verbose_name='owner INN number'),
),
migrations.AddField(
model_name='autoevaluationmodel',
name='worked_hours',
field=models.IntegerField(blank=True, null=True, verbose_name='worked hours'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='rate_type',
field=models.CharField(blank=True, choices=[('auto', 'Automobil'), ('real_estate', "Ko'chmas mulk"), ('equipment', 'Uskuna')], max_length=50, null=True, verbose_name='rate type'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='status',
field=models.CharField(choices=[('pending', 'Kutilmoqda'), ('in_progress', 'Jarayonda'), ('completed', 'Bajarildi'), ('rejected', 'Rad etildi')], default='pending', max_length=50, verbose_name='status'),
),
]

View File

@@ -0,0 +1,51 @@
# Generated by Django 5.2.7 on 2026-03-10 08:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0018_autoevaluationmodel_chassi_and_more'),
]
operations = [
migrations.RemoveField(
model_name='autoevaluationmodel',
name='chassi',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='customer_inn_number',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='location_lat',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='location_lng',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='need_delivering',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='owner_inn_number',
),
migrations.RemoveField(
model_name='autoevaluationmodel',
name='worked_hours',
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='rate_type',
field=models.IntegerField(blank=True, choices=[(1, "Kredit ta'minoti sifatida garovga qo'yish"), (2, 'Sotish maqsadida bozor qiymatini aniqlash'), (3, 'Soliqqa tortish maqsadida'), (4, 'Boshqa')], null=True, verbose_name='rate type'),
),
migrations.AlterField(
model_name='autoevaluationmodel',
name='status',
field=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'),
),
]

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -3,6 +3,19 @@ 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,
FormOwnership,
LocationConvenience,
LocationHighways,
ObjectOwnerType,
PropertyRights,
RateType,
ValueDetermined,
)
from .valuation import ValuationModel
from .vehicle import VehicleModel
@@ -14,17 +27,260 @@ class AutoEvaluationModel(AbstractBaseModel):
on_delete=models.CASCADE,
related_name="auto_detail",
verbose_name=_("valuation"),
null=True,
blank=True,
)
vehicle = models.OneToOneField(
VehicleModel,
on_delete=models.CASCADE,
related_name="evaluation",
verbose_name=_("vehicle"),
null=True,
blank=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,
)
rate_object_name = models.CharField(
verbose_name=_("rate object name"),
max_length=255,
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,
)
property_rights = models.IntegerField(
verbose_name=_("property rights"),
choices=PropertyRights.choices,
blank=True,
null=True,
)
form_ownership = models.IntegerField(
verbose_name=_("form of ownership"),
choices=FormOwnership.choices,
blank=True,
null=True,
)
value_determined = models.IntegerField(
verbose_name=_("value determined"),
choices=ValueDetermined.choices,
blank=True,
null=True,
)
rate_type = models.IntegerField(
verbose_name=_("rate type"),
choices=RateType.choices,
blank=True,
null=True,
)
# ── Step 3 — Manzil ma'lumotlari ────────────────────────────────
object_location_province = models.CharField(
verbose_name=_("object location province"),
max_length=100,
blank=True,
null=True,
)
object_location_district = models.CharField(
verbose_name=_("object location district"),
max_length=100,
blank=True,
null=True,
)
object_location_city = models.CharField(
verbose_name=_("object location city"),
max_length=100,
blank=True,
null=True,
)
object_location_neighborhood = models.CharField(
verbose_name=_("object location neighborhood"),
max_length=100,
blank=True,
null=True,
)
object_location_street = models.CharField(
verbose_name=_("object location street"),
max_length=100,
blank=True,
null=True,
)
object_location_home = models.CharField(
verbose_name=_("object location home"),
max_length=50,
blank=True,
null=True,
)
object_location_highways = models.IntegerField(
verbose_name=_("location highways"),
choices=LocationHighways.choices,
blank=True,
null=True,
)
object_location_covenience = models.IntegerField(
verbose_name=_("location convenience"),
choices=LocationConvenience.choices,
blank=True,
null=True,
)
# ── 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,
)
def __str__(self):
return f"Auto Evaluation for {self.valuation}"
return f"Auto Evaluation {self.registration_number or self.pk}"
@classmethod
def _baker(cls):

View File

@@ -3,8 +3,7 @@ from django.utils.translation import gettext_lazy as _
from django_core.models import AbstractBaseModel
from model_bakery import baker
from core.apps.evaluation.choices.vehicle import FuelType, BodyType, VehicleCondition
from core.apps.evaluation.choices.quick import CarType, QuickEvaluationStatus
class QuickEvaluationModel(AbstractBaseModel):
@@ -16,46 +15,115 @@ class QuickEvaluationModel(AbstractBaseModel):
related_name="quick_evaluations",
verbose_name=_("created by"),
)
tech_passport_number = models.CharField(
verbose_name=_("tech passport number"), max_length=50, blank=True, null=True
# Tex passport
tex_passport_serie_num = models.CharField(
verbose_name=_("tech passport series and number"),
max_length=20,
blank=True,
null=True,
)
license_plate = models.CharField(
verbose_name=_("license plate"), max_length=20, blank=True, null=True
tech_passport_issued_date = models.DateField(
verbose_name=_("tech passport issued date"),
blank=True,
null=True,
)
model = models.CharField(verbose_name=_("model"), max_length=255, blank=True, null=True)
brand = models.CharField(verbose_name=_("brand"), max_length=255, blank=True, null=True)
manufacture_year = models.IntegerField(
verbose_name=_("manufacture year"), blank=True, null=True
tech_passport_issued_place = models.CharField(
verbose_name=_("tech passport issued place"),
max_length=255,
blank=True,
null=True,
)
tex_passport_file = models.FileField(
verbose_name=_("tech passport file"),
upload_to="quick_evaluation/tech_passports/%Y/%m/",
blank=True,
null=True,
)
# Car info
car_type = models.CharField(
verbose_name=_("car type"),
max_length=50,
choices=CarType.choices,
blank=True,
null=True,
)
brand = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_brands",
verbose_name=_("brand"),
)
marka = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_markas",
verbose_name=_("marka"),
)
car_position = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_positions",
verbose_name=_("car position"),
)
distance_covered = models.IntegerField(
verbose_name=_("distance covered (km)"),
blank=True,
null=True,
)
body_type = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_body_types",
verbose_name=_("body type"),
)
mileage = models.IntegerField(verbose_name=_("mileage"), blank=True, null=True)
vin_number = models.CharField(
verbose_name=_("VIN number"), max_length=50, blank=True, null=True
)
car_number = models.CharField(
verbose_name=_("car number"), max_length=20, blank=True, null=True
)
car_manufactured_date = models.IntegerField(
verbose_name=_("manufacture year"), blank=True, null=True
)
engine_number = models.CharField(
verbose_name=_("engine number"), max_length=50, blank=True, null=True
)
color = models.CharField(verbose_name=_("color"), max_length=50, blank=True, null=True)
fuel_type = models.CharField(
color = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_colors",
verbose_name=_("color"),
)
fuel_type = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="quick_eval_fuel_types",
verbose_name=_("fuel type"),
max_length=50,
choices=FuelType.choices,
blank=True,
null=True,
)
body_type = models.CharField(
verbose_name=_("body type"),
max_length=50,
choices=BodyType.choices,
blank=True,
state_car = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
)
condition = models.CharField(
verbose_name=_("condition"),
max_length=50,
choices=VehicleCondition.choices,
blank=True,
null=True,
related_name="quick_eval_states",
verbose_name=_("car state"),
)
# Result
estimated_price = models.DecimalField(
verbose_name=_("estimated price"),
max_digits=15,
@@ -63,6 +131,12 @@ class QuickEvaluationModel(AbstractBaseModel):
blank=True,
null=True,
)
status = models.CharField(
verbose_name=_("status"),
max_length=50,
choices=QuickEvaluationStatus.choices,
default=QuickEvaluationStatus.CREATED,
)
def __str__(self):
return f"Quick Evaluation {self.pk} by {self.created_by}"

View File

@@ -9,14 +9,14 @@ from core.apps.evaluation.choices.real_estate import PropertyType, RealEstateCon
class RealEstateEvaluationModel(AbstractBaseModel):
valuation = models.OneToOneField(
ValuationModel,
"evaluation.ValuationModel",
on_delete=models.CASCADE,
related_name="real_estate_detail",
verbose_name=_("valuation"),
)
property_type = models.CharField(
verbose_name=_("property type"),
max_length=50,

View File

@@ -0,0 +1,38 @@
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.reference import ReferenceType
class ReferenceitemModel(AbstractBaseModel):
type = models.CharField(
verbose_name=_("type"),
max_length=50,
choices=ReferenceType.choices,
)
name = models.CharField(verbose_name=_("name"), max_length=255)
parent = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="children",
verbose_name=_("parent"),
)
order = models.IntegerField(verbose_name=_("order"), default=0)
is_active = models.BooleanField(verbose_name=_("is active"), default=True)
def __str__(self):
return f"{self.get_type_display()}: {self.name}"
@classmethod
def _baker(cls):
return baker.make(cls)
class Meta:
db_table = "ReferenceItem"
verbose_name = _("Reference Item")
verbose_name_plural = _("Reference Items")
ordering = ["type", "order", "name"]

View File

@@ -3,8 +3,7 @@ from django.utils.translation import gettext_lazy as _
from django_core.models import AbstractBaseModel
from model_bakery import baker
from core.apps.evaluation.choices.vehicle import FuelType, BodyType, VehicleCondition
from core.apps.evaluation.choices.vehicle import VehicleCondition
class VehicleModel(AbstractBaseModel):
@@ -25,11 +24,21 @@ class VehicleModel(AbstractBaseModel):
license_plate = models.CharField(
verbose_name=_("license plate"), max_length=20, blank=True, null=True
)
brand = models.CharField(
verbose_name=_("brand"), max_length=100, blank=True, null=True
brand = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_brands",
verbose_name=_("brand"),
)
model = models.CharField(
verbose_name=_("model"), max_length=100, blank=True, null=True
model = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_models",
verbose_name=_("model"),
)
manufacture_year = models.IntegerField(
verbose_name=_("manufacture year"), blank=True, null=True
@@ -40,27 +49,34 @@ class VehicleModel(AbstractBaseModel):
engine_number = models.CharField(
verbose_name=_("engine number"), max_length=50, blank=True, null=True
)
color = models.CharField(
verbose_name=_("color"), max_length=50, blank=True, null=True
color = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_colors",
verbose_name=_("color"),
)
# 🛠 Texnik holati
mileage = models.IntegerField(
verbose_name=_("mileage"), blank=True, null=True, help_text=_("Distance in km")
)
fuel_type = models.CharField(
fuel_type = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_fuel_types",
verbose_name=_("fuel type"),
max_length=20,
choices=FuelType.choices,
blank=True,
null=True,
)
body_type = models.CharField(
verbose_name=_("body type"),
max_length=20,
choices=BodyType.choices,
blank=True,
body_type = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_body_types",
verbose_name=_("body type"),
)
condition = models.CharField(
verbose_name=_("condition"),
@@ -69,12 +85,19 @@ class VehicleModel(AbstractBaseModel):
blank=True,
null=True,
)
position = models.CharField(
verbose_name=_("position"), max_length=50, blank=True, null=True
position = models.ForeignKey(
"evaluation.ReferenceitemModel",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="vehicle_positions",
verbose_name=_("position"),
)
def __str__(self):
return f"{self.brand} {self.model} ({self.license_plate})"
brand_name = self.brand.name if self.brand else ""
model_name = self.model.name if self.model else ""
return f"{brand_name} {model_name} ({self.license_plate})"
@classmethod
def _baker(cls):

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1,12 @@
from rest_framework import permissions
class ReferenceitemPermission(permissions.BasePermission):
def __init__(self) -> None: ...
def __call__(self, *args, **kwargs):
return self
def has_permission(self, request, view):
return True

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -1,30 +1,190 @@
import re
from rest_framework import serializers
from core.apps.evaluation.models import AutoEvaluationModel
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)
rate_type_display = serializers.CharField(source="get_rate_type_display", read_only=True, default=None)
value_determined_display = serializers.CharField(source="get_value_determined_display", read_only=True, default=None)
object_owner_type_display = serializers.CharField(source="get_object_owner_type_display", read_only=True, default=None)
property_rights_display = serializers.CharField(source="get_property_rights_display", read_only=True, default=None)
form_ownership_display = serializers.CharField(source="get_form_ownership_display", read_only=True, default=None)
class Meta:
model = AutoEvaluationModel
fields = [
"id",
"valuation",
"vehicle",
"registration_number",
"object_type",
"object_type_display",
"car_brand",
"car_model",
"car_number",
"manufacture_year",
"car_color",
"rate_type",
"rate_type_display",
"value_determined",
"value_determined_display",
"status",
"status_display",
"created_at",
]
class ListAutoevaluationSerializer(BaseAutoevaluationSerializer):
class Meta(BaseAutoevaluationSerializer.Meta): ...
class Meta(BaseAutoevaluationSerializer.Meta):
pass
class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
class Meta(BaseAutoevaluationSerializer.Meta): ...
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)
object_location_highways_display = serializers.CharField(
source="get_object_location_highways_display", read_only=True, default=None
)
object_location_covenience_display = serializers.CharField(
source="get_object_location_covenience_display", read_only=True, default=None
)
class CreateAutoevaluationSerializer(BaseAutoevaluationSerializer):
class Meta(BaseAutoevaluationSerializer.Meta):
fields = [
"id",
fields = BaseAutoevaluationSerializer.Meta.fields + [
# Step 1
"contract_date",
"object_inspection_date",
"rate_date",
"rate_report_date",
"rate_object_name",
# Step 2
"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",
"property_rights",
"property_rights_display",
"form_ownership",
"form_ownership_display",
# Step 3
"object_location_province",
"object_location_district",
"object_location_city",
"object_location_neighborhood",
"object_location_street",
"object_location_home",
"object_location_highways",
"object_location_highways_display",
"object_location_covenience",
"object_location_covenience_display",
# Step 4
"tex_passport_serie_num",
"tex_passport_gived_date",
"tex_passport_gived_location",
"car_type",
"car_type_display",
"car_wheel",
"car_wheel_display",
"car_dvigatel_number",
# Extra
"valuation",
"vehicle",
"rating_goal",
"updated_at",
]
class CreateAutoevaluationSerializer(serializers.ModelSerializer):
class Meta:
model = AutoEvaluationModel
fields = [
# Step 1
"registration_number",
"contract_date",
"object_inspection_date",
"rate_date",
"rate_report_date",
"rate_object_name",
"object_type",
# Step 2
"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",
"property_rights",
"form_ownership",
"value_determined",
"rate_type",
# Step 3
"object_location_province",
"object_location_district",
"object_location_city",
"object_location_neighborhood",
"object_location_street",
"object_location_home",
"object_location_highways",
"object_location_covenience",
# Step 4
"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

View File

@@ -1,27 +1,70 @@
from rest_framework import serializers
from core.apps.evaluation.models import CustomerModel
class BaseCustomerSerializer(serializers.ModelSerializer):
customer_type_display = serializers.CharField(source="get_customer_type_display", read_only=True)
class Meta:
model = CustomerModel
fields = [
"id",
"customer_type",
"customer_type_display",
"jshshir",
"passport_series",
"passport_number",
"first_name",
"last_name",
"middle_name",
"inn",
"org_name",
"created_at",
]
class ListCustomerSerializer(BaseCustomerSerializer):
class Meta(BaseCustomerSerializer.Meta): ...
class Meta(BaseCustomerSerializer.Meta):
fields = [
"id",
"customer_type_display",
"first_name",
"last_name",
"org_name",
"inn",
"jshshir",
]
class RetrieveCustomerSerializer(BaseCustomerSerializer):
class Meta(BaseCustomerSerializer.Meta): ...
class Meta(BaseCustomerSerializer.Meta):
fields = BaseCustomerSerializer.Meta.fields + [
"address",
"passport_issued_date",
"passport_issued_by",
"org_address",
"director_name",
"mfo",
"bank_account",
"certificate_file",
"updated_at",
]
class CreateCustomerSerializer(BaseCustomerSerializer):
class Meta(BaseCustomerSerializer.Meta):
fields = [
"id",
"customer_type",
"jshshir",
"passport_series",
"passport_number",
"first_name",
"last_name",
"middle_name",
"address",
"passport_issued_date",
"passport_issued_by",
"inn",
"org_name",
"org_address",
"director_name",
"mfo",
"bank_account",
"certificate_file",
]

View File

@@ -1,27 +1,70 @@
from rest_framework import serializers
from core.apps.evaluation.models import PropertyOwnerModel
class BasePropertyOwnerSerializer(serializers.ModelSerializer):
owner_type_display = serializers.CharField(source="get_owner_type_display", read_only=True)
class Meta:
model = PropertyOwnerModel
fields = [
"id",
"owner_type",
"owner_type_display",
"jshshir",
"passport_series",
"passport_number",
"first_name",
"last_name",
"middle_name",
"inn",
"org_name",
"created_at",
]
class ListPropertyOwnerSerializer(BasePropertyOwnerSerializer):
class Meta(BasePropertyOwnerSerializer.Meta): ...
class Meta(BasePropertyOwnerSerializer.Meta):
fields = [
"id",
"owner_type_display",
"first_name",
"last_name",
"org_name",
"inn",
"jshshir",
]
class RetrievePropertyOwnerSerializer(BasePropertyOwnerSerializer):
class Meta(BasePropertyOwnerSerializer.Meta): ...
class Meta(BasePropertyOwnerSerializer.Meta):
fields = BasePropertyOwnerSerializer.Meta.fields + [
"address",
"passport_issued_date",
"passport_issued_by",
"org_address",
"director_name",
"mfo",
"bank_account",
"certificate_file",
"updated_at",
]
class CreatePropertyOwnerSerializer(BasePropertyOwnerSerializer):
class Meta(BasePropertyOwnerSerializer.Meta):
fields = [
"id",
"owner_type",
"jshshir",
"passport_series",
"passport_number",
"first_name",
"last_name",
"middle_name",
"address",
"passport_issued_date",
"passport_issued_by",
"inn",
"org_name",
"org_address",
"director_name",
"mfo",
"bank_account",
"certificate_file",
]

View File

@@ -1,28 +1,47 @@
from rest_framework import serializers
from core.apps.evaluation.models import ValuationDocumentModel
class BaseValuationdocumentSerializer(serializers.ModelSerializer):
document_type_display = serializers.CharField(source="get_document_type_display", read_only=True)
uploaded_by_name = serializers.CharField(source="uploaded_by.get_full_name", read_only=True)
class Meta:
model = ValuationDocumentModel
fields = [
"id",
"valuation",
"document_type",
"document_type_display",
"title",
"file",
"uploaded_by",
"uploaded_by_name",
"created_at",
]
class ListValuationdocumentSerializer(BaseValuationdocumentSerializer):
class Meta(BaseValuationdocumentSerializer.Meta): ...
class Meta(BaseValuationdocumentSerializer.Meta):
fields = [
"id",
"valuation",
"document_type_display",
"title",
"file",
]
class RetrieveValuationdocumentSerializer(BaseValuationdocumentSerializer):
class Meta(BaseValuationdocumentSerializer.Meta): ...
class Meta(BaseValuationdocumentSerializer.Meta):
fields = BaseValuationdocumentSerializer.Meta.fields + [
"description",
"updated_at",
]
class CreateValuationdocumentSerializer(BaseValuationdocumentSerializer):
class Meta(BaseValuationdocumentSerializer.Meta):
fields = [
"id",
"valuation",
"document_type",
"title",
"file",
"description",
]

View File

@@ -1,28 +1,50 @@
from rest_framework import serializers
from core.apps.evaluation.models import MovablePropertyEvaluationModel
class BaseMovablepropertyevaluationSerializer(serializers.ModelSerializer):
property_category_display = serializers.CharField(source="get_property_category_display", read_only=True)
condition_display = serializers.CharField(source="get_condition_display", read_only=True)
class Meta:
model = MovablePropertyEvaluationModel
fields = [
"id",
# "name",
"valuation",
"property_name",
"property_category",
"property_category_display",
"serial_number",
"manufacture_year",
"condition",
"condition_display",
"quantity",
]
class ListMovablepropertyevaluationSerializer(BaseMovablepropertyevaluationSerializer):
class Meta(BaseMovablepropertyevaluationSerializer.Meta): ...
class Meta(BaseMovablepropertyevaluationSerializer.Meta):
fields = [
"id",
"valuation",
"property_name",
"property_category_display",
"quantity",
]
class RetrieveMovablepropertyevaluationSerializer(BaseMovablepropertyevaluationSerializer):
class Meta(BaseMovablepropertyevaluationSerializer.Meta): ...
class Meta(BaseMovablepropertyevaluationSerializer.Meta):
fields = BaseMovablepropertyevaluationSerializer.Meta.fields + [
"created_at",
"updated_at",
]
class CreateMovablepropertyevaluationSerializer(BaseMovablepropertyevaluationSerializer):
class Meta(BaseMovablepropertyevaluationSerializer.Meta):
fields = [
"id",
# "name",
"valuation",
"property_name",
"property_category",
"serial_number",
"manufacture_year",
"condition",
"quantity",
]

View File

@@ -1,26 +1,127 @@
import re
from rest_framework import serializers
from core.apps.evaluation.models import QuickEvaluationModel
class BaseQuickevaluationSerializer(serializers.ModelSerializer):
created_by_name = serializers.CharField(source="created_by.get_full_name", read_only=True)
status_display = serializers.CharField(source="get_status_display", read_only=True)
car_type_display = serializers.CharField(source="get_car_type_display", read_only=True)
brand_name = serializers.CharField(source="brand.name", read_only=True, default=None)
marka_name = serializers.CharField(source="marka.name", read_only=True, default=None)
color_name = serializers.CharField(source="color.name", read_only=True, default=None)
fuel_type_name = serializers.CharField(source="fuel_type.name", read_only=True, default=None)
body_type_name = serializers.CharField(source="body_type.name", read_only=True, default=None)
state_car_name = serializers.CharField(source="state_car.name", read_only=True, default=None)
car_position_name = serializers.CharField(source="car_position.name", read_only=True, default=None)
class Meta:
model = QuickEvaluationModel
fields = [
"id",
"created_by",
"created_by_name",
"brand",
"brand_name",
"marka",
"marka_name",
"car_number",
"car_manufactured_date",
"estimated_price",
"status",
"status_display",
"car_type",
"car_type_display",
"state_car",
"state_car_name",
"created_at",
]
class ListQuickevaluationSerializer(BaseQuickevaluationSerializer):
class Meta(BaseQuickevaluationSerializer.Meta): ...
class Meta(BaseQuickevaluationSerializer.Meta):
pass
class RetrieveQuickevaluationSerializer(BaseQuickevaluationSerializer):
class Meta(BaseQuickevaluationSerializer.Meta): ...
class CreateQuickevaluationSerializer(BaseQuickevaluationSerializer):
class Meta(BaseQuickevaluationSerializer.Meta):
fields = [
"id",
fields = BaseQuickevaluationSerializer.Meta.fields + [
"tex_passport_serie_num",
"tech_passport_issued_date",
"tech_passport_issued_place",
"tex_passport_file",
"car_position",
"car_position_name",
"distance_covered",
"body_type",
"body_type_name",
"vin_number",
"engine_number",
"color",
"color_name",
"fuel_type",
"fuel_type_name",
"updated_at",
]
class CreateQuickevaluationSerializer(serializers.ModelSerializer):
class Meta:
model = QuickEvaluationModel
fields = [
"tex_passport_serie_num",
"tech_passport_issued_date",
"tech_passport_issued_place",
"tex_passport_file",
"car_type",
"brand",
"marka",
"car_position",
"distance_covered",
"body_type",
"vin_number",
"car_number",
"car_manufactured_date",
"engine_number",
"color",
"fuel_type",
"state_car",
]
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_vin_number(self, value):
if value and len(value) != 17:
raise serializers.ValidationError("VIN raqami 17 belgidan iborat bo'lishi kerak.")
return value
def validate(self, attrs):
car_type = attrs.get("car_type")
if car_type == "lightweight":
if not attrs.get("distance_covered"):
raise serializers.ValidationError(
{"distance_covered": "car_type 'lightweight' uchun majburiy."}
)
if not attrs.get("body_type"):
raise serializers.ValidationError(
{"body_type": "car_type 'lightweight' uchun majburiy."}
)
if car_type == "truck":
if not attrs.get("vin_number"):
raise serializers.ValidationError(
{"vin_number": "car_type 'truck' uchun majburiy."}
)
return attrs
def create(self, validated_data):
request = self.context.get("request")
if request and request.user and request.user.is_authenticated:
validated_data["created_by"] = request.user
return super().create(validated_data)

View File

@@ -1,15 +1,17 @@
from rest_framework import serializers
from core.apps.evaluation.models import RealEstateEvaluationModel
class BaseRealestateevaluationSerializer(serializers.ModelSerializer):
property_type_display = serializers.CharField(source="get_property_type_display", read_only=True)
condition_display = serializers.CharField(source="get_condition_display", read_only=True)
class Meta:
model = RealEstateEvaluationModel
fields = [
"id",
"valuation",
"property_type",
"property_type_display",
"address",
"cadastral_number",
"total_area",
@@ -19,22 +21,31 @@ class BaseRealestateevaluationSerializer(serializers.ModelSerializer):
"rooms_count",
"build_year",
"condition",
"condition_display",
"has_renovation",
]
class ListRealestateevaluationSerializer(BaseRealestateevaluationSerializer):
class Meta(BaseRealestateevaluationSerializer.Meta): ...
class Meta(BaseRealestateevaluationSerializer.Meta):
fields = [
"id",
"valuation",
"property_type_display",
"address",
"total_area",
"condition_display",
]
class RetrieveRealestateevaluationSerializer(BaseRealestateevaluationSerializer):
class Meta(BaseRealestateevaluationSerializer.Meta): ...
class Meta(BaseRealestateevaluationSerializer.Meta):
fields = BaseRealestateevaluationSerializer.Meta.fields + [
"created_at",
"updated_at",
]
class CreateRealestateevaluationSerializer(BaseRealestateevaluationSerializer):
class Meta(BaseRealestateevaluationSerializer.Meta):
fields = [
"id",
"valuation",
"property_type",
"address",

View File

@@ -0,0 +1,48 @@
from rest_framework import serializers
from core.apps.evaluation.models import ReferenceitemModel
class BaseReferenceitemSerializer(serializers.ModelSerializer):
type_display = serializers.CharField(source="get_type_display", read_only=True)
parent_name = serializers.CharField(source="parent.name", read_only=True, default=None)
class Meta:
model = ReferenceitemModel
fields = [
"id",
"type",
"type_display",
"name",
"parent",
"parent_name",
"order",
"is_active",
]
class ListReferenceitemSerializer(BaseReferenceitemSerializer):
class Meta(BaseReferenceitemSerializer.Meta):
pass
class RetrieveReferenceitemSerializer(BaseReferenceitemSerializer):
children = serializers.SerializerMethodField()
class Meta(BaseReferenceitemSerializer.Meta):
fields = BaseReferenceitemSerializer.Meta.fields + ["children"]
def get_children(self, obj):
children = obj.children.filter(is_active=True).order_by("order", "name")
return ListReferenceitemSerializer(children, many=True).data
class CreateReferenceitemSerializer(BaseReferenceitemSerializer):
class Meta(BaseReferenceitemSerializer.Meta):
fields = [
"type",
"name",
"parent",
"order",
"is_active",
]

View File

@@ -0,0 +1 @@
from .ReferenceItem import * # noqa

View File

@@ -1,35 +1,46 @@
from rest_framework import serializers
from core.apps.evaluation.models import EvaluationReportModel
class BaseEvaluationreportSerializer(serializers.ModelSerializer):
evaluator_name = serializers.CharField(source="evaluator.get_full_name", read_only=True)
valuation_number = serializers.CharField(source="valuation.conclusion_number", read_only=True)
class Meta:
model = EvaluationReportModel
fields = [
"id",
"valuation",
"valuation_number",
"evaluator",
"evaluator_name",
"report_number",
"final_value",
"report_file",
"conclusion_text",
"approved_at",
"created_at",
]
class ListEvaluationreportSerializer(BaseEvaluationreportSerializer):
class Meta(BaseEvaluationreportSerializer.Meta):
fields = [
"id",
"valuation_number",
"evaluator_name",
"report_number",
"final_value",
"approved_at",
]
class ListEvaluationreportSerializer(BaseEvaluationreportSerializer):
class Meta(BaseEvaluationreportSerializer.Meta): ...
class RetrieveEvaluationreportSerializer(BaseEvaluationreportSerializer):
class Meta(BaseEvaluationreportSerializer.Meta): ...
class Meta(BaseEvaluationreportSerializer.Meta):
fields = BaseEvaluationreportSerializer.Meta.fields + [
"conclusion_text",
"updated_at",
]
class CreateEvaluationreportSerializer(BaseEvaluationreportSerializer):
class Meta(BaseEvaluationreportSerializer.Meta):
fields = [
"id",
"valuation",
"evaluator",
"report_number",

View File

@@ -1,40 +1,56 @@
from rest_framework import serializers
from core.apps.evaluation.models import ValuationModel
class BaseValuationSerializer(serializers.ModelSerializer):
status_display = serializers.CharField(source="get_status_display", read_only=True)
evaluation_type_display = serializers.CharField(source="get_evaluation_type_display", read_only=True)
payment_status_display = serializers.CharField(source="get_payment_status_display", read_only=True)
customer_name = serializers.CharField(source="customer.__str__", read_only=True)
class Meta:
model = ValuationModel
fields = [
"id",
"conclusion_number",
"customer",
"customer_name",
"evaluation_purpose",
"evaluation_type",
"evaluation_type_display",
"status",
"status_display",
"created_at",
]
class ListValuationSerializer(BaseValuationSerializer):
class Meta(BaseValuationSerializer.Meta):
pass
fields = BaseValuationSerializer.Meta.fields + [
"final_price",
"payment_status_display",
]
class RetrieveValuationSerializer(BaseValuationSerializer):
created_by_name = serializers.CharField(source="created_by.get_full_name", read_only=True)
assigned_to_name = serializers.CharField(source="assigned_to.get_full_name", read_only=True)
class Meta(BaseValuationSerializer.Meta):
fields = BaseValuationSerializer.Meta.fields + [
"customer",
"property_owner",
"created_by",
"created_by_name",
"assigned_to",
"assigned_to_name",
"evaluation_subtype",
"estimated_price",
"final_price",
"payment_status",
"payment_status_display",
"is_courier_delivery",
"courier_extra_amount",
"notes",
"updated_at",
]
class CreateValuationSerializer(BaseValuationSerializer):
class Meta(BaseValuationSerializer.Meta):
fields = [
@@ -46,4 +62,3 @@ class CreateValuationSerializer(BaseValuationSerializer):
"is_courier_delivery",
"notes",
]

View File

@@ -4,14 +4,28 @@ from core.apps.evaluation.models import VehicleModel
class BaseVehicleSerializer(serializers.ModelSerializer):
brand_name = serializers.CharField(source="brand.name", read_only=True, default=None)
model_name = serializers.CharField(source="model.name", read_only=True, default=None)
color_name = serializers.CharField(source="color.name", read_only=True, default=None)
fuel_type_name = serializers.CharField(source="fuel_type.name", read_only=True, default=None)
body_type_name = serializers.CharField(source="body_type.name", read_only=True, default=None)
condition_display = serializers.CharField(source="get_condition_display", read_only=True)
position_name = serializers.CharField(source="position.name", read_only=True, default=None)
class Meta:
model = VehicleModel
fields = [
"id",
"brand",
"brand_name",
"model",
"model_name",
"license_plate",
"manufacture_year",
"color",
"color_name",
"fuel_type_name",
"condition_display",
]
@@ -22,18 +36,54 @@ class ListVehicleSerializer(BaseVehicleSerializer):
class RetrieveVehicleSerializer(BaseVehicleSerializer):
class Meta(BaseVehicleSerializer.Meta):
fields = "__all__"
fields = [
"id",
"tech_passport_series",
"tech_passport_number",
"tech_passport_issued_date",
"tech_passport_issued_by",
"license_plate",
"brand",
"brand_name",
"model",
"model_name",
"manufacture_year",
"vin_number",
"engine_number",
"color",
"color_name",
"mileage",
"fuel_type",
"fuel_type_name",
"body_type",
"body_type_name",
"condition",
"condition_display",
"position",
"position_name",
"created_at",
"updated_at",
]
class CreateVehicleSerializer(BaseVehicleSerializer):
class Meta(BaseVehicleSerializer.Meta):
class CreateVehicleSerializer(serializers.ModelSerializer):
class Meta:
model = VehicleModel
fields = [
"tech_passport_series",
"tech_passport_number",
"tech_passport_issued_date",
"tech_passport_issued_by",
"license_plate",
"brand",
"model",
"manufacture_year",
"vin_number",
"engine_number",
"color",
"mileage",
"fuel_type",
"body_type",
"condition",
"position",
]

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1,8 @@
from django.db.models.signals import post_save
from django.dispatch import receiver
from core.apps.evaluation.models import ReferenceitemModel
@receiver(post_save, sender=ReferenceitemModel)
def ReferenceitemSignal(sender, instance, created, **kwargs): ...

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1 @@
from .test_ReferenceItem import * # noqa

View File

@@ -0,0 +1,101 @@
import pytest
from django.urls import reverse
from rest_framework.test import APIClient
from core.apps.evaluation.models import ReferenceitemModel
@pytest.fixture
def instance(db):
return ReferenceitemModel._baker()
@pytest.fixture
def api_client(instance):
client = APIClient()
##client.force_authenticate(user=instance.user)
return client, instance
@pytest.fixture
def data(api_client):
client, instance = api_client
return (
{
"list": reverse("reference-item-list"),
"retrieve": reverse("reference-item-detail", kwargs={"pk": instance.pk}),
"retrieve-not-found": reverse("reference-item-detail", kwargs={"pk": 1000}),
},
client,
instance,
)
@pytest.mark.django_db
def test_list(data):
urls, client, _ = data
response = client.get(urls["list"])
data_resp = response.json()
assert response.status_code == 200
assert data_resp["status"] is True
@pytest.mark.django_db
def test_retrieve(data):
urls, client, _ = data
response = client.get(urls["retrieve"])
data_resp = response.json()
assert response.status_code == 200
assert data_resp["status"] is True
@pytest.mark.django_db
def test_retrieve_not_found(data):
urls, client, _ = data
response = client.get(urls["retrieve-not-found"])
data_resp = response.json()
assert response.status_code == 404
assert data_resp["status"] is False
# @pytest.mark.django_db
# def test_create(data):
# urls, client, _ = data
# response = client.post(urls["list"], data={"name": "test"})
# assert response.json()["status"] is True
# assert response.status_code == 201
# @pytest.mark.django_db
# def test_update(data):
# urls, client, _ = data
# response = client.patch(urls["retrieve"], data={"name": "updated"})
# assert response.json()["status"] is True
# assert response.status_code == 200
#
# # verify updated value
# response = client.get(urls["retrieve"])
# assert response.json()["status"] is True
# assert response.status_code == 200
# assert response.json()["data"]["name"] == "updated"
# @pytest.mark.django_db
# def test_partial_update():
# urls, client, _ = data
# response = client.patch(urls["retrieve"], data={"name": "updated"})
# assert response.json()["status"] is True
# assert response.status_code == 200
#
# # verify updated value
# response = client.get(urls["retrieve"])
# assert response.json()["status"] is True
# assert response.status_code == 200
# assert response.json()["data"]["name"] == "updated"
# @pytest.mark.django_db
# def test_destroy(data):
# urls, client, _ = data
# response = client.delete(urls["retrieve"])
# assert response.status_code == 204

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1,8 @@
from modeltranslation.translator import TranslationOptions, register
from core.apps.evaluation.models import ReferenceitemModel
@register(ReferenceitemModel)
class ReferenceitemTranslation(TranslationOptions):
fields = []

View File

@@ -9,12 +9,14 @@ from .views import (
PropertyOwnerView,
QuickEvaluationView,
RealEstateEvaluationView,
ReferenceitemView,
ValuationDocumentView,
ValuationView,
VehicleView,
)
router = DefaultRouter()
router.register("reference-item", ReferenceitemView, basename="reference-item")
router.register("valuation-document", ValuationDocumentView, basename="valuation-document")
router.register("evaluation-report", EvaluationReportView, basename="evaluation-report")
router.register("quick-evaluation", QuickEvaluationView, basename="quick-evaluation")

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -0,0 +1,8 @@
# from django.core.exceptions import ValidationError
class ReferenceitemValidator:
def __init__(self): ...
def __call__(self):
return True

View File

@@ -4,6 +4,7 @@ from .document import * # noqa
from .movable import * # noqa
from .quick import * # noqa
from .real_estate import * # noqa
from .reference import * # noqa
from .report import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -1,8 +1,11 @@
from django_core.mixins import BaseViewSetMixin
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import AllowAny
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.viewsets import ModelViewSet
from core.apps.evaluation.filters.auto import AutoevaluationFilter
from core.apps.evaluation.models import AutoEvaluationModel
from core.apps.evaluation.serializers.auto import (
CreateAutoevaluationSerializer,
@@ -12,11 +15,52 @@ from core.apps.evaluation.serializers.auto import (
@extend_schema(tags=["AutoEvaluation"])
class AutoEvaluationView(BaseViewSetMixin, ReadOnlyModelViewSet):
queryset = AutoEvaluationModel.objects.all()
class AutoEvaluationView(BaseViewSetMixin, ModelViewSet):
queryset = AutoEvaluationModel.objects.select_related(
"valuation",
"valuation__customer",
"vehicle",
).all()
serializer_class = ListAutoevaluationSerializer
permission_classes = [AllowAny]
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_class = AutoevaluationFilter
search_fields = [
"registration_number",
"car_model",
"car_brand",
"car_number",
]
ordering_fields = [
"registration_number",
"contract_date",
"object_inspection_date",
"rate_date",
"rate_report_date",
"rate_object_name",
"object_type",
"object_owner_type",
"object_location_province",
"object_location_district",
"object_location_city",
"tex_passport_serie_num",
"tex_passport_gived_date",
"car_brand",
"car_model",
"car_number",
"manufacture_year",
"car_color",
"property_rights",
"form_ownership",
"value_determined",
"rate_type",
"status",
"created_at",
"updated_at",
]
ordering = ["-created_at"]
action_permission_classes = {}
action_serializer_class = {
"list": ListAutoevaluationSerializer,

View File

@@ -1,8 +1,12 @@
from django_core.mixins import BaseViewSetMixin
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.permissions import AllowAny
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.viewsets import ModelViewSet
from core.apps.evaluation.filters.quick import QuickevaluationFilter
from core.apps.evaluation.models import QuickEvaluationModel
from core.apps.evaluation.serializers.quick import (
CreateQuickevaluationSerializer,
@@ -12,10 +16,33 @@ from core.apps.evaluation.serializers.quick import (
@extend_schema(tags=["QuickEvaluation"])
class QuickEvaluationView(BaseViewSetMixin, ReadOnlyModelViewSet):
queryset = QuickEvaluationModel.objects.all()
class QuickEvaluationView(BaseViewSetMixin, ModelViewSet):
queryset = QuickEvaluationModel.objects.select_related(
"created_by", "brand", "marka", "color", "fuel_type",
"body_type", "state_car", "car_position",
).all()
serializer_class = ListQuickevaluationSerializer
permission_classes = [AllowAny]
parser_classes = [MultiPartParser, FormParser]
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_class = QuickevaluationFilter
search_fields = ["car_number", "marka__name", "brand__name"]
ordering_fields = [
"created_at",
"updated_at",
"car_number",
"brand__name",
"marka__name",
"car_type",
"car_manufactured_date",
"color__name",
"fuel_type__name",
"state_car__name",
"status",
"distance_covered",
]
ordering = ["-created_at"]
action_permission_classes = {}
action_serializer_class = {

View File

@@ -0,0 +1,34 @@
from django_core.mixins import BaseViewSetMixin
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.permissions import AllowAny
from rest_framework.viewsets import ReadOnlyModelViewSet
from core.apps.evaluation.filters.reference import ReferenceitemFilter
from core.apps.evaluation.models import ReferenceitemModel
from core.apps.evaluation.serializers.reference import (
CreateReferenceitemSerializer,
ListReferenceitemSerializer,
RetrieveReferenceitemSerializer,
)
@extend_schema(tags=["ReferenceItem"])
class ReferenceitemView(BaseViewSetMixin, ReadOnlyModelViewSet):
queryset = ReferenceitemModel.objects.select_related("parent").filter(is_active=True)
serializer_class = ListReferenceitemSerializer
permission_classes = [AllowAny]
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_class = ReferenceitemFilter
search_fields = ["name"]
ordering_fields = ["name", "order", "type"]
ordering = ["order", "name"]
action_permission_classes = {}
action_serializer_class = {
"list": ListReferenceitemSerializer,
"retrieve": RetrieveReferenceitemSerializer,
"create": CreateReferenceitemSerializer,
}

View File

@@ -13,7 +13,9 @@ from core.apps.evaluation.serializers.vehicle import (
@extend_schema(tags=["Vehicle"])
class VehicleView(BaseViewSetMixin, ReadOnlyModelViewSet):
queryset = VehicleModel.objects.all()
queryset = VehicleModel.objects.select_related(
"brand", "model", "color", "fuel_type", "body_type", "position",
).all()
serializer_class = ListVehicleSerializer
permission_classes = [AllowAny]

View File

@@ -29,7 +29,7 @@ class PaymentAdmin(ModelAdmin):
"note",
)
readonly_fields = ("created_at", "updated_at")
raw_id_fields = ("valuation", "payer")
autocomplete_fields = ("valuation", "payer")
fieldsets = (
("To'lov ma'lumotlari", {
"fields": (

View File

@@ -1,28 +1,58 @@
from rest_framework import serializers
from core.apps.payment.models import PaymentModel
class BasePaymentSerializer(serializers.ModelSerializer):
payment_method_display = serializers.CharField(source="get_payment_method_display", read_only=True)
status_display = serializers.CharField(source="get_status_display", read_only=True)
payer_name = serializers.CharField(source="payer.get_full_name", read_only=True)
valuation_number = serializers.CharField(source="valuation.conclusion_number", read_only=True)
class Meta:
model = PaymentModel
fields = [
"id",
"valuation",
"valuation_number",
"payer",
"payer_name",
"amount",
"payment_method",
"payment_method_display",
"status",
"status_display",
"transaction_id",
"paid_at",
"created_at",
]
class ListPaymentSerializer(BasePaymentSerializer):
class Meta(BasePaymentSerializer.Meta): ...
class Meta(BasePaymentSerializer.Meta):
fields = [
"id",
"valuation_number",
"payer_name",
"amount",
"payment_method_display",
"status_display",
"paid_at",
]
class RetrievePaymentSerializer(BasePaymentSerializer):
class Meta(BasePaymentSerializer.Meta): ...
class Meta(BasePaymentSerializer.Meta):
fields = BasePaymentSerializer.Meta.fields + [
"note",
"updated_at",
]
class CreatePaymentSerializer(BasePaymentSerializer):
class Meta(BasePaymentSerializer.Meta):
fields = [
"id",
"valuation",
"payer",
"amount",
"payment_method",
"status",
"transaction_id",
"paid_at",
"note",
]

View File

@@ -84,7 +84,7 @@ services:
max-file: "5"
web:
image: husanjon/sifatbaho:36
image: husanjon/sifatbaho:45
env_file:
- .env
environment: