38 Commits

Author SHA1 Message Date
github-actions[bot]
28fdf82c08 🔄 Update image to 49 [CI SKIP] 2026-03-17 14:38:21 +00:00
a06cf173b6 Merge pull request 'Baholash maqsadi uchun api chiqarildi' (#30) from feat/valuation-purpose-api into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m59s
Reviewed-on: #30
2026-03-17 14:36:47 +00:00
Husanjonazamov
9593b02c2d Baholash maqsadi uchun api chiqarildi 2026-03-17 19:36:21 +05:00
386e9ead89 Merge pull request 'user request yuborishda api fix qilindi' (#29) from fix/user-request into main
Some checks failed
Deploy to Production / build-and-deploy (push) Failing after 1m34s
Reviewed-on: #29
2026-03-17 14:07:08 +00:00
Husanjonazamov
9a13a2b4f0 user request yuborishda api fix qilindi 2026-03-17 19:06:38 +05:00
github-actions[bot]
9b57611b62 🔄 Update image to 47 [CI SKIP] 2026-03-17 13:27:52 +00:00
4479a0c1a5 Merge pull request 'use modeliga avatar fieldni qoshildi' (#28) from feat/user into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m34s
Reviewed-on: #28
2026-03-17 13:25:41 +00:00
Husanjonazamov
0d574a92a9 use modeliga avatar fieldni qoshildi 2026-03-17 18:25:20 +05:00
github-actions[bot]
397f239b1d 🔄 Update image to 46 [CI SKIP] 2026-03-10 09:06:20 +00:00
7bcf7bdc7f Merge pull request 'user ariza uchun requesty yaratish uchun api chiqarildi' (#27) from feat/evaluation-request-api into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m6s
Reviewed-on: #27
2026-03-10 09:04:34 +00:00
Husanjonazamov
93757b0342 user ariza uchun requesty yaratish uchun api chiqarildi 2026-03-10 14:02:48 +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
cdf2f40a9c Merge pull request 'admin fayllari to'g'irlandi' (#17) from feat/all-admins into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 3m7s
Reviewed-on: #17
2026-02-18 13:16:45 +00:00
Husanjonazamov
cba724e2d0 admin fayllari to'g'irlandi 2026-02-18 18:16:20 +05:00
github-actions[bot]
cd3037e55f 🔄 Update image to 36 [CI SKIP] 2026-02-18 13:10:40 +00:00
101 changed files with 3654 additions and 209 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

@@ -6,26 +6,121 @@ PAGES = [
"seperator": False,
"items": [
{
"title": _("Home page"),
"title": _("Bosh sahifa"),
"icon": "home",
"link": reverse_lazy("admin:index"),
}
],
},
{
"title": _("Auth"),
"separator": True, # Top border
"title": _("Foydalanuvchilar"),
"separator": True,
"items": [
{
"title": _("Users"),
"title": _("Foydalanuvchilar"),
"icon": "group",
"link": reverse_lazy("admin:http_user_changelist"),
"link": reverse_lazy("admin:accounts_user_changelist"),
},
{
"title": _("Group"),
"icon": "group",
"title": _("Guruhlar"),
"icon": "admin_panel_settings",
"link": reverse_lazy("admin:auth_group_changelist"),
},
],
},
{
"title": _("Buyurtmachilar"),
"separator": True,
"items": [
{
"title": _("Buyurtmachilar"),
"icon": "person",
"link": reverse_lazy("admin:evaluation_customermodel_changelist"),
},
{
"title": _("Mulk egalari"),
"icon": "badge",
"link": reverse_lazy("admin:evaluation_propertyownermodel_changelist"),
},
],
},
{
"title": _("Arizalar"),
"separator": True,
"items": [
{
"title": _("Baholash so'rovlari"),
"icon": "rate_review",
"link": reverse_lazy("admin:evaluation_evaluationrequestmodel_changelist"),
},
{
"title": _("Barcha arizalar"),
"icon": "description",
"link": reverse_lazy("admin:evaluation_valuationmodel_changelist"),
},
{
"title": _("Ariza hujjatlari"),
"icon": "attach_file",
"link": reverse_lazy("admin:evaluation_valuationdocumentmodel_changelist"),
},
],
},
{
"title": _("Baholash turlari"),
"separator": True,
"items": [
{
"title": _("Avto baholash"),
"icon": "directions_car",
"link": reverse_lazy("admin:evaluation_autoevaluationmodel_changelist"),
},
{
"title": _("Transport vositalari"),
"icon": "car_repair",
"link": reverse_lazy("admin:evaluation_vehiclemodel_changelist"),
},
{
"title": _("Ko'chmas mulk"),
"icon": "home_work",
"link": reverse_lazy("admin:evaluation_realestateevaluationmodel_changelist"),
},
{
"title": _("Ko'char mulk"),
"icon": "inventory_2",
"link": reverse_lazy("admin:evaluation_movablepropertyevaluationmodel_changelist"),
},
{
"title": _("Tezkor baholash"),
"icon": "bolt",
"link": reverse_lazy("admin:evaluation_quickevaluationmodel_changelist"),
},
],
},
{
"title": _("Natijalar"),
"separator": True,
"items": [
{
"title": _("Hisobotlar"),
"icon": "summarize",
"link": reverse_lazy("admin:evaluation_evaluationreportmodel_changelist"),
},
{
"title": _("To'lovlar"),
"icon": "payments",
"link": reverse_lazy("admin:payment_paymentmodel_changelist"),
},
],
},
{
"title": _("Ma'lumotnomalari"),
"separator": True,
"items": [
{
"title": _("Ma'lumotnomalar"),
"icon": "category",
"link": reverse_lazy("admin:evaluation_referenceitemmodel_changelist"),
},
],
},
]

View File

@@ -90,6 +90,6 @@ UNFOLD = {
"SIDEBAR": {
"show_search": True,
"show_all_applications": True,
# "navigation": navigation.PAGES,
"navigation": navigation.PAGES,
},
}

View File

@@ -13,7 +13,7 @@ from config.env import env
def home(request):
return HttpResponse("OK: #d4d8c18a2af33ce72feb7e1ad5c71ba65c25e6b2")
return HttpResponse("OK: #a06cf173b69ce36a54b5e1cacd87c2f1b8edf6e9")
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

@@ -1,5 +1,6 @@
from django.contrib.auth import admin
from django.utils.translation import gettext_lazy as _
from django.utils.safestring import mark_safe
from unfold.admin import ModelAdmin
from unfold.forms import AdminPasswordChangeForm # UserCreationForm,
from unfold.forms import UserChangeForm
@@ -10,13 +11,15 @@ class CustomUserAdmin(admin.UserAdmin, ModelAdmin):
# add_form = UserCreationForm
form = UserChangeForm
list_display = (
"display_avatar",
"first_name",
"last_name",
"phone",
"role",
)
search_fields = ("phone", "first_name", "last_name", "username")
autocomplete_fields = ["groups", "user_permissions"]
fieldsets = ((None, {"fields": ("phone",)}),) + (
fieldsets = ((None, {"fields": ("phone", "avatar",)}),) + (
(None, {"fields": ("username", "password")}),
(_("Personal info"), {"fields": ("first_name", "last_name", "email")}),
(
@@ -35,6 +38,15 @@ class CustomUserAdmin(admin.UserAdmin, ModelAdmin):
(_("Important dates"), {"fields": ("last_login", "date_joined")}),
)
def display_avatar(self, obj):
if obj.avatar:
return mark_safe(
f'<img src="{obj.avatar.url}" width="35" height="35" style="border-radius: 50%; object-fit: cover;" />'
)
return _("No Image")
display_avatar.short_description = _("Avatar")
class PermissionAdmin(ModelAdmin):
list_display = ("name",)

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2026-03-17 12:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_alter_user_role'),
]
operations = [
migrations.AddField(
model_name='user',
name='avatar',
field=models.ImageField(blank=True, null=True, upload_to='avatars/'),
),
]

View File

@@ -16,6 +16,7 @@ class User(auth_models.AbstractUser):
choices=RoleChoice,
default=RoleChoice.USER,
)
avatar = models.ImageField(upload_to="avatars/", null=True, blank=True)
USERNAME_FIELD = "phone"
objects = UserManager()

View File

@@ -19,5 +19,6 @@ class UserUpdateSerializer(serializers.ModelSerializer):
model = get_user_model()
fields = [
"first_name",
"last_name"
"last_name",
"avatar"
]

View File

@@ -6,7 +6,7 @@ from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _
from django_core import exceptions
from drf_spectacular.utils import extend_schema
from rest_framework import status, throttling, request
from rest_framework import status, throttling, request, parsers
from rest_framework.response import Response
from rest_framework.exceptions import PermissionDenied
from rest_framework.viewsets import GenericViewSet
@@ -160,6 +160,11 @@ class ResetPasswordView(BaseViewSetMixin, GenericViewSet, UserService):
@extend_schema(tags=["me"])
class MeView(BaseViewSetMixin, GenericViewSet, UserService):
permission_classes = [IsAuthenticated]
parser_classes = (
parsers.MultiPartParser,
parsers.FormParser,
parsers.JSONParser,
)
def get_serializer_class(self):
match self.action:

View File

@@ -4,6 +4,8 @@ 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 .request import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa

View File

@@ -5,8 +5,71 @@ from core.apps.evaluation.models import AutoEvaluationModel
@admin.register(AutoEvaluationModel)
class AutoevaluationAdmin(ModelAdmin):
class AutoEvaluationAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"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 = (
"registration_number",
"car_brand",
"car_model",
"car_number",
)
readonly_fields = ("created_at", "updated_at")
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

@@ -8,7 +8,51 @@ from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
class CustomerAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"customer_type",
"first_name",
"last_name",
"jshshir",
"inn",
"org_name",
"created_at",
)
list_filter = ("customer_type",)
search_fields = (
"first_name",
"last_name",
"jshshir",
"passport_number",
"inn",
"org_name",
)
readonly_fields = ("created_at", "updated_at")
fieldsets = (
("Umumiy", {
"fields": ("customer_type",),
}),
("Jismoniy shaxs", {
"fields": (
"jshshir",
("passport_series", "passport_number"),
("first_name", "last_name", "middle_name"),
"address",
("passport_issued_date", "passport_issued_by"),
),
}),
("Yuridik shaxs", {
"fields": (
"inn",
"org_name",
"org_address",
"director_name",
("mfo", "bank_account"),
"certificate_file",
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)
@@ -16,6 +60,49 @@ class CustomerAdmin(ModelAdmin):
class PropertyOwnerAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"owner_type",
"first_name",
"last_name",
"jshshir",
"inn",
"org_name",
"created_at",
)
list_filter = ("owner_type",)
search_fields = (
"first_name",
"last_name",
"jshshir",
"passport_number",
"inn",
"org_name",
)
readonly_fields = ("created_at", "updated_at")
fieldsets = (
("Umumiy", {
"fields": ("owner_type",),
}),
("Jismoniy shaxs", {
"fields": (
"jshshir",
("passport_series", "passport_number"),
("first_name", "last_name", "middle_name"),
"address",
("passport_issued_date", "passport_issued_by"),
),
}),
("Yuridik shaxs", {
"fields": (
"inn",
"org_name",
"org_address",
"director_name",
("mfo", "bank_account"),
"certificate_file",
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -5,8 +5,38 @@ from core.apps.evaluation.models import ValuationDocumentModel
@admin.register(ValuationDocumentModel)
class ValuationdocumentAdmin(ModelAdmin):
class ValuationDocumentAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"valuation",
"document_type",
"title",
"uploaded_by",
"created_at",
)
list_filter = ("document_type",)
search_fields = (
"title",
"description",
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("valuation", "uploaded_by")
fieldsets = (
("Hujjat", {
"fields": (
"valuation",
"document_type",
"title",
"file",
"uploaded_by",
),
}),
("Qo'shimcha", {
"fields": ("description",),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -5,8 +5,46 @@ from core.apps.evaluation.models import MovablePropertyEvaluationModel
@admin.register(MovablePropertyEvaluationModel)
class MovablepropertyevaluationAdmin(ModelAdmin):
class MovablePropertyEvaluationAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"valuation",
"property_name",
"property_category",
"serial_number",
"manufacture_year",
"condition",
"quantity",
)
list_filter = (
"property_category",
"condition",
)
search_fields = (
"property_name",
"serial_number",
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("valuation",)
fieldsets = (
("Ariza", {
"fields": ("valuation",),
}),
("Mulk ma'lumotlari", {
"fields": (
"property_name",
"property_category",
"serial_number",
"manufacture_year",
"quantity",
),
}),
("Holat", {
"fields": ("condition",),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -5,8 +5,63 @@ from core.apps.evaluation.models import QuickEvaluationModel
@admin.register(QuickEvaluationModel)
class QuickevaluationAdmin(ModelAdmin):
class QuickEvaluationAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"created_by",
"brand",
"marka",
"car_number",
"car_manufactured_date",
"estimated_price",
"status",
"car_type",
"state_car",
"created_at",
)
list_filter = (
"status",
"car_type",
)
search_fields = (
"car_number",
"vin_number",
"engine_number",
"tex_passport_serie_num",
)
readonly_fields = ("created_at", "updated_at")
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": (
"car_number",
("brand", "marka"),
("car_manufactured_date", "color"),
("vin_number", "engine_number"),
("distance_covered", "car_position"),
),
}),
("Texnik holat", {
"fields": (
("fuel_type", "body_type"),
("car_type", "state_car"),
),
}),
("Natija", {
"fields": ("estimated_price", "status"),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -5,8 +5,56 @@ from core.apps.evaluation.models import RealEstateEvaluationModel
@admin.register(RealEstateEvaluationModel)
class RealestateevaluationAdmin(ModelAdmin):
class RealEstateEvaluationAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"valuation",
"property_type",
"address",
"total_area",
"floor",
"build_year",
"condition",
)
list_filter = (
"property_type",
"condition",
"has_renovation",
)
search_fields = (
"address",
"cadastral_number",
"valuation__conclusion_number",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("valuation",)
fieldsets = (
("Ariza", {
"fields": ("valuation",),
}),
("Mulk ma'lumotlari", {
"fields": (
"property_type",
"address",
"cadastral_number",
),
}),
("Texnik parametrlar", {
"fields": (
("total_area", "living_area"),
("floor", "total_floors"),
"rooms_count",
"build_year",
),
}),
("Holat", {
"fields": (
"condition",
"has_renovation",
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

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

@@ -5,8 +5,46 @@ from core.apps.evaluation.models import EvaluationReportModel
@admin.register(EvaluationReportModel)
class EvaluationreportAdmin(ModelAdmin):
class EvaluationReportAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"report_number",
"valuation",
"evaluator",
"final_value",
"approved_at",
"created_at",
)
list_filter = ("approved_at",)
search_fields = (
"report_number",
"valuation__conclusion_number",
"evaluator__phone",
"evaluator__first_name",
"conclusion_text",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("valuation", "evaluator")
fieldsets = (
("Hisobot", {
"fields": (
"report_number",
"valuation",
"evaluator",
),
}),
("Natija", {
"fields": (
"final_value",
"conclusion_text",
"report_file",
),
}),
("Tasdiqlash", {
"fields": ("approved_at",),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -0,0 +1,63 @@
from django.contrib import admin
from unfold.admin import ModelAdmin
from core.apps.evaluation.models import EvaluationrequestModel
@admin.register(EvaluationrequestModel)
class EvaluationrequestAdmin(ModelAdmin):
list_display = (
"id",
"user",
"rate_type",
"object_type",
"customer_inn_number",
"owner_inn_number",
"status",
"need_delivering",
"created_at",
)
list_filter = ("status", "rate_type", "object_type", "need_delivering")
search_fields = (
"customer_inn_number",
"owner_inn_number",
"tex_passport",
"user__phone",
)
readonly_fields = ("user", "created_at", "updated_at")
fieldsets = (
("Asosiy", {
"fields": (
"user",
"rate_type",
"object_type",
"status",
),
}),
("Buyurtmachi", {
"fields": (
("customer_inn_number", "owner_inn_number"),
"tex_passport",
),
}),
("Baholash parametrlari", {
"fields": (
("value_determined", "rate_goal"),
("property_rights", "form_ownership"),
),
}),
("Qo'shimcha (truck_car)", {
"classes": ("collapse",),
"fields": ("worked_hours", "chassi"),
}),
("Yetkazish", {
"fields": (
"need_delivering",
("location_lat", "location_lng"),
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -8,5 +8,66 @@ from core.apps.evaluation.models import ValuationModel
class ValuationAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"conclusion_number",
"evaluation_type",
"status",
"customer",
"assigned_to",
"estimated_price",
"final_price",
"payment_status",
"created_at",
)
list_filter = (
"evaluation_type",
"status",
"payment_status",
"evaluation_purpose",
"is_courier_delivery",
)
search_fields = (
"conclusion_number",
"customer__first_name",
"customer__last_name",
"customer__org_name",
"customer__inn",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("customer", "property_owner", "created_by", "assigned_to")
fieldsets = (
("Asosiy ma'lumotlar", {
"fields": (
"conclusion_number",
("evaluation_type", "evaluation_subtype"),
"evaluation_purpose",
"status",
),
}),
("Bog'lanishlar", {
"fields": (
"customer",
"property_owner",
"created_by",
"assigned_to",
),
}),
("Narx va To'lov", {
"fields": (
("estimated_price", "final_price"),
"payment_status",
),
}),
("Yetkazib berish", {
"fields": (
"is_courier_delivery",
"courier_extra_amount",
),
}),
("Qo'shimcha", {
"fields": ("notes",),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

View File

@@ -8,5 +8,54 @@ from core.apps.evaluation.models import VehicleModel
class VehicleAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"brand",
"model",
"license_plate",
"manufacture_year",
"color",
"fuel_type",
"condition",
"mileage",
)
list_filter = (
"condition",
"manufacture_year",
)
search_fields = (
"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": (
("tech_passport_series", "tech_passport_number"),
("tech_passport_issued_date", "tech_passport_issued_by"),
),
}),
("Transport ma'lumotlari", {
"fields": (
("brand", "model"),
"license_plate",
("manufacture_year", "color"),
("vin_number", "engine_number"),
"position",
),
}),
("Texnik holat", {
"fields": (
("fuel_type", "body_type"),
"condition",
"mileage",
),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

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,13 @@
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")
EVALUATION_PURPOSE = "evaluation_purpose", _("Evaluation purpose")

View File

@@ -0,0 +1,21 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class EvaluationRateType(models.TextChoices):
AUTO = "auto", _("Automobil")
REAL_ESTATE = "real_estate", _("Ko'chmas mulk")
EQUIPMENT = "equipment", _("Uskuna")
class RequestObjectType(models.TextChoices):
LIGHTWEIGHT_AUTO = "lightweight_auto", _("Yengil automobil")
TRUCK_CAR = "truck_car", _("Yuk automobil")
SPECIAL_TECH = "special_tech", _("Maxsus texnika")
class RequestStatus(models.TextChoices):
PENDING = "pending", _("Kutilmoqda")
IN_PROGRESS = "in_progress", _("Jarayonda")
COMPLETED = "completed", _("Bajarildi")
REJECTED = "rejected", _("Rad etildi")

View File

@@ -4,6 +4,8 @@ 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 .request 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

@@ -0,0 +1,35 @@
from django_filters import rest_framework as filters
from core.apps.evaluation.models import EvaluationrequestModel
class EvaluationrequestFilter(filters.FilterSet):
rate_type = filters.CharFilter(field_name="rate_type", lookup_expr="exact")
object_type = filters.CharFilter(field_name="object_type", lookup_expr="exact")
status = filters.CharFilter(field_name="status", lookup_expr="exact")
need_delivering = filters.BooleanFilter(field_name="need_delivering")
customer_inn_number = filters.CharFilter(
field_name="customer_inn_number", lookup_expr="icontains"
)
owner_inn_number = filters.CharFilter(
field_name="owner_inn_number", lookup_expr="icontains"
)
tex_passport = filters.CharFilter(
field_name="tex_passport", lookup_expr="icontains"
)
date_from = filters.DateFilter(field_name="created_at", lookup_expr="gte")
date_to = filters.DateFilter(field_name="created_at", lookup_expr="lte")
class Meta:
model = EvaluationrequestModel
fields = [
"rate_type",
"object_type",
"status",
"need_delivering",
"customer_inn_number",
"owner_inn_number",
"tex_passport",
"date_from",
"date_to",
]

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,8 @@ 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 .request 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,10 @@
from django import forms
from core.apps.evaluation.models import EvaluationrequestModel
class EvaluationrequestForm(forms.ModelForm):
class Meta:
model = EvaluationrequestModel
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,45 @@
# Generated by Django 5.2.7 on 2026-03-10 08:34
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0017_autoevaluationmodel_car_brand_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='EvaluationrequestModel',
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)),
('rate_type', models.CharField(choices=[('auto', 'Automobil'), ('real_estate', "Ko'chmas mulk"), ('equipment', 'Uskuna')], max_length=50, verbose_name='rate type')),
('object_type', models.CharField(blank=True, choices=[('lightweight_auto', 'Yengil automobil'), ('truck_car', 'Yuk automobil'), ('special_tech', 'Maxsus texnika')], max_length=50, null=True, verbose_name='object type')),
('customer_inn_number', models.CharField(max_length=20, verbose_name='customer INN number')),
('owner_inn_number', models.CharField(max_length=20, verbose_name='owner INN number')),
('tex_passport', models.CharField(blank=True, max_length=20, null=True, verbose_name='tex passport')),
('value_determined', models.CharField(max_length=100, verbose_name='value determined')),
('rate_goal', models.CharField(max_length=100, verbose_name='rate goal')),
('property_rights', models.CharField(max_length=100, verbose_name='property rights')),
('form_ownership', models.CharField(max_length=100, verbose_name='form ownership')),
('worked_hours', models.IntegerField(blank=True, null=True, verbose_name='worked hours')),
('chassi', models.IntegerField(blank=True, null=True, verbose_name='chassi')),
('need_delivering', models.BooleanField(default=True, verbose_name='need delivering')),
('location_lat', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True, verbose_name='location latitude')),
('location_lng', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True, verbose_name='location longitude')),
('status', models.CharField(choices=[('pending', 'Kutilmoqda'), ('in_progress', 'Jarayonda'), ('completed', 'Bajarildi'), ('rejected', 'Rad etildi')], default='pending', max_length=50, verbose_name='status')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='evaluation_requests', to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'Evaluation Request',
'verbose_name_plural': 'Evaluation Requests',
'db_table': 'EvaluationRequest',
},
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.2.7 on 2026-03-17 13:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0018_evaluationrequestmodel'),
]
operations = [
migrations.AddField(
model_name='evaluationrequestmodel',
name='location_name',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='location name'),
),
migrations.AlterField(
model_name='evaluationrequestmodel',
name='chassi',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='chassi'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2026-03-17 14:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('evaluation', '0019_evaluationrequestmodel_location_name_and_more'),
]
operations = [
migrations.AlterField(
model_name='referenceitemmodel',
name='type',
field=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'), ('evaluation_purpose', 'Evaluation purpose')], max_length=50, verbose_name='type'),
),
]

View File

@@ -4,6 +4,8 @@ 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 .request 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

@@ -0,0 +1,126 @@
from django.conf import settings
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.request import (
EvaluationRateType,
RequestObjectType,
RequestStatus,
)
class EvaluationrequestModel(AbstractBaseModel):
user = models.ForeignKey(
"accounts.User",
on_delete=models.CASCADE,
related_name="evaluation_requests",
verbose_name=_("user"),
)
rate_type = models.CharField(
verbose_name=_("rate type"),
max_length=50,
choices=EvaluationRateType.choices,
)
object_type = models.CharField(
verbose_name=_("object type"),
max_length=50,
choices=RequestObjectType.choices,
blank=True,
null=True,
)
customer_inn_number = models.CharField(
verbose_name=_("customer INN number"),
max_length=20,
)
owner_inn_number = models.CharField(
verbose_name=_("owner INN number"),
max_length=20,
)
tex_passport = models.CharField(
verbose_name=_("tex passport"),
max_length=20,
blank=True,
null=True,
)
value_determined = models.CharField(
verbose_name=_("value determined"),
max_length=100,
)
rate_goal = models.CharField(
verbose_name=_("rate goal"),
max_length=100,
)
property_rights = models.CharField(
verbose_name=_("property rights"),
max_length=100,
)
form_ownership = models.CharField(
verbose_name=_("form ownership"),
max_length=100,
)
worked_hours = models.IntegerField(
verbose_name=_("worked hours"),
blank=True,
null=True,
)
chassi = models.CharField(
verbose_name=_("chassi"),
max_length=100,
blank=True,
null=True,
)
need_delivering = models.BooleanField(
verbose_name=_("need delivering"),
default=True,
)
location_name = models.CharField(
verbose_name=_("location name"),
max_length=255,
blank=True,
null=True,
)
location_lat = models.DecimalField(
verbose_name=_("location latitude"),
max_digits=9,
decimal_places=6,
blank=True,
null=True,
)
location_lng = models.DecimalField(
verbose_name=_("location longitude"),
max_digits=9,
decimal_places=6,
blank=True,
null=True,
)
status = models.CharField(
verbose_name=_("status"),
max_length=50,
choices=RequestStatus.choices,
default=RequestStatus.PENDING,
)
def __str__(self):
return f"Request #{self.pk}{self.get_rate_type_display()}"
@classmethod
def _baker(cls):
user = baker.make(settings.AUTH_USER_MODEL)
return baker.make(
cls,
user=user,
rate_type=EvaluationRateType.AUTO,
customer_inn_number="123456789",
owner_inn_number="987654321",
value_determined="Bozor qiymati",
rate_goal="Kredit uchun",
property_rights="Xususiy",
form_ownership="Xususiy",
)
class Meta:
db_table = "EvaluationRequest"
verbose_name = _("Evaluation Request")
verbose_name_plural = _("Evaluation Requests")

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,8 @@ 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 .request 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

@@ -0,0 +1,12 @@
from rest_framework import permissions
class EvaluationrequestPermission(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,8 @@ 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 .request 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,57 @@
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",
]
class EvaluationPurposeSerializer(serializers.ModelSerializer):
label = serializers.CharField(source="name")
value = serializers.IntegerField(source="id")
class Meta:
model = ReferenceitemModel
fields = ["label", "value"]

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

@@ -0,0 +1,142 @@
import re
from rest_framework import serializers
from core.apps.evaluation.models import EvaluationrequestModel
class BaseEvaluationrequestSerializer(serializers.ModelSerializer):
rate_type_display = serializers.CharField(
source="get_rate_type_display", read_only=True
)
object_type_display = serializers.CharField(
source="get_object_type_display", read_only=True, default=None
)
status_display = serializers.CharField(
source="get_status_display", read_only=True
)
location = serializers.SerializerMethodField()
location_name = serializers.CharField(required=False)
class Meta:
model = EvaluationrequestModel
fields = [
"id",
"rate_type",
"rate_type_display",
"object_type",
"object_type_display",
"customer_inn_number",
"owner_inn_number",
"tex_passport",
"value_determined",
"rate_goal",
"property_rights",
"form_ownership",
"worked_hours",
"chassi",
"need_delivering",
"location",
"location_name",
"status",
"status_display",
"created_at",
"updated_at",
]
def get_location(self, obj):
if obj.location_lat is not None and obj.location_lng is not None:
return {
"lat": float(obj.location_lat),
"lng": float(obj.location_lng),
"name": obj.location_name
}
return None
class ListEvaluationrequestSerializer(BaseEvaluationrequestSerializer):
class Meta(BaseEvaluationrequestSerializer.Meta):
pass
class RetrieveEvaluationrequestSerializer(BaseEvaluationrequestSerializer):
class Meta(BaseEvaluationrequestSerializer.Meta):
pass
class CreateEvaluationrequestSerializer(serializers.ModelSerializer):
location = serializers.DictField(required=False)
# Frontend may send locationName
locationName = serializers.CharField(write_only=True, required=False)
class Meta:
model = EvaluationrequestModel
fields = [
"rate_type",
"object_type",
"customer_inn_number",
"owner_inn_number",
"tex_passport",
"value_determined",
"rate_goal",
"property_rights",
"form_ownership",
"worked_hours",
"chassi",
"need_delivering",
"location",
"locationName",
]
def validate_tex_passport(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):
rate_type = attrs.get("rate_type")
object_type = attrs.get("object_type")
# object_type majburiy agar rate_type=auto
if rate_type == "auto" and not object_type:
raise serializers.ValidationError(
{"object_type": "rate_type 'auto' bo'lganda object_type majburiy."}
)
# tex_passport majburiy agar rate_type=auto
if rate_type == "auto" and not attrs.get("tex_passport"):
raise serializers.ValidationError(
{"tex_passport": "rate_type 'auto' bo'lganda tex_passport majburiy."}
)
# worked_hours va chassi faqat yuk automobil uchun majburiy (truck_car)
if object_type == "truck_car":
if attrs.get("worked_hours") is None:
raise serializers.ValidationError(
{"worked_hours": "Yuk automobil uchun ishlagan soati majburiy."}
)
if attrs.get("chassi") is None:
raise serializers.ValidationError(
{"chassi": "Yuk automobil uchun shassi majburiy."}
)
return attrs
def create(self, validated_data):
location = validated_data.pop("location", None)
location_name = validated_data.pop("locationName", None)
if location:
validated_data["location_lat"] = location.get("lat")
validated_data["location_lng"] = location.get("lng")
if not location_name:
location_name = location.get("name") or location.get("locationName")
if location_name:
validated_data["location_name"] = location_name
validated_data["user"] = self.context["request"].user
return super().create(validated_data)

View File

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

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,8 @@ 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 .request 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

@@ -0,0 +1,27 @@
from django.db.models.signals import pre_save
from django.dispatch import receiver
from core.apps.evaluation.choices.request import RequestStatus
from core.apps.evaluation.models import EvaluationrequestModel
@receiver(pre_save, sender=EvaluationrequestModel)
def create_evaluation_on_approve(sender, instance, **kwargs):
if not instance.pk:
return
try:
old = EvaluationrequestModel.objects.get(pk=instance.pk)
except EvaluationrequestModel.DoesNotExist:
return
if old.status != RequestStatus.COMPLETED and instance.status == RequestStatus.COMPLETED:
from core.apps.evaluation.models import AutoEvaluationModel
if instance.rate_type == "auto" and not hasattr(instance, "_evaluation_created"):
AutoEvaluationModel.objects.create(
object_type=instance.object_type or "",
tex_passport_serie_num=instance.tex_passport or "",
rating_goal=instance.rate_goal or "",
)
instance._evaluation_created = True

View File

@@ -4,6 +4,8 @@ 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 .request 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

@@ -0,0 +1 @@
from .test_EvaluationRequest 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 EvaluationrequestModel
@pytest.fixture
def instance(db):
return EvaluationrequestModel._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("evaluation-request-list"),
"retrieve": reverse("evaluation-request-detail", kwargs={"pk": instance.pk}),
"retrieve-not-found": reverse("evaluation-request-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,8 @@ 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 .request 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

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

View File

@@ -5,16 +5,22 @@ from .views import (
AutoEvaluationView,
CustomerView,
EvaluationReportView,
EvaluationrequestView,
MovablePropertyEvaluationView,
PropertyOwnerView,
QuickEvaluationView,
RealEstateEvaluationView,
ReferenceitemView,
ValuationDocumentView,
ValuationView,
VehicleView,
EvaluationPurposeView,
)
router = DefaultRouter()
router.register("evaluation-purpose", EvaluationPurposeView, basename="evaluation-purpose")
router.register("evaluation-request", EvaluationrequestView, basename="evaluation-request")
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,8 @@ 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 .request 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

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

View File

@@ -4,6 +4,8 @@ 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 .request 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,50 @@
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,
EvaluationPurposeSerializer,
)
@extend_schema(tags=["EvaluationPurpose"])
class EvaluationPurposeView(BaseViewSetMixin, ReadOnlyModelViewSet):
queryset = ReferenceitemModel.objects.filter(
type="evaluation_purpose", is_active=True
).order_by("order", "name")
serializer_class = EvaluationPurposeSerializer
permission_classes = [AllowAny]
pagination_class = None
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
search_fields = ["name"]
ordering_fields = ["name", "order"]
ordering = ["order", "name"]
@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

@@ -0,0 +1,56 @@
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.pagination import PageNumberPagination
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.viewsets import ModelViewSet
from core.apps.evaluation.filters.request import EvaluationrequestFilter
from core.apps.evaluation.models import EvaluationrequestModel
from core.apps.evaluation.serializers.request import (
CreateEvaluationrequestSerializer,
ListEvaluationrequestSerializer,
RetrieveEvaluationrequestSerializer,
)
# class RequestPagination(PageNumberPagination):
# page_size = 20
# page_size_query_param = "limit"
# max_page_size = 100
@extend_schema(tags=["EvaluationRequest"])
class EvaluationrequestView(BaseViewSetMixin, ModelViewSet):
serializer_class = ListEvaluationrequestSerializer
permission_classes = [IsAuthenticated]
# pagination_class = RequestPagination
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_class = EvaluationrequestFilter
search_fields = [
"customer_inn_number",
"owner_inn_number",
"tex_passport",
]
ordering_fields = [
"created_at",
"updated_at",
"rate_type",
"object_type",
"status",
]
ordering = ["-created_at"]
action_permission_classes = {}
action_serializer_class = {
"list": ListEvaluationrequestSerializer,
"retrieve": RetrieveEvaluationrequestSerializer,
"create": CreateEvaluationrequestSerializer,
}
def get_queryset(self):
return EvaluationrequestModel.objects.filter(
user=self.request.user
).order_by("-created_at")

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

@@ -8,5 +8,48 @@ from core.apps.payment.models import PaymentModel
class PaymentAdmin(ModelAdmin):
list_display = (
"id",
"__str__",
"valuation",
"payer",
"amount",
"payment_method",
"status",
"transaction_id",
"paid_at",
"created_at",
)
list_filter = (
"status",
"payment_method",
)
search_fields = (
"transaction_id",
"valuation__conclusion_number",
"payer__phone",
"payer__first_name",
"note",
)
readonly_fields = ("created_at", "updated_at")
autocomplete_fields = ("valuation", "payer")
fieldsets = (
("To'lov ma'lumotlari", {
"fields": (
"valuation",
"payer",
("amount", "payment_method"),
"status",
),
}),
("Tranzaksiya", {
"fields": (
"transaction_id",
"paid_at",
),
}),
("Qo'shimcha", {
"fields": ("note",),
}),
("Tizim", {
"classes": ("collapse",),
"fields": ("created_at", "updated_at"),
}),
)

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",
]

Some files were not shown because too many files have changed in this diff Show More