evaluation-customer modeli yaratildi va kerakli fiealdlr qoshildi
This commit is contained in:
18
core/apps/accounts/migrations/0002_alter_user_role.py
Normal file
18
core/apps/accounts/migrations/0002_alter_user_role.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-02-12 10:18
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='user',
|
||||||
|
name='role',
|
||||||
|
field=models.CharField(choices=[('superuser', 'Superuser'), ('admin', 'Admin'), ('user', 'User'), ('evaluator', 'Evaluator'), ('dealer', 'Dealer'), ('client', 'Client')], default='user', max_length=255),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
|
|||||||
21
core/apps/evaluation/admin/customer.py
Normal file
21
core/apps/evaluation/admin/customer.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from unfold.admin import ModelAdmin
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(CustomerModel)
|
||||||
|
class CustomerAdmin(ModelAdmin):
|
||||||
|
list_display = (
|
||||||
|
"id",
|
||||||
|
"__str__",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(PropertyOwnerModel)
|
||||||
|
class PropertyOwnerAdmin(ModelAdmin):
|
||||||
|
list_display = (
|
||||||
|
"id",
|
||||||
|
"__str__",
|
||||||
|
)
|
||||||
|
|
||||||
1
core/apps/evaluation/filters/__init__.py
Normal file
1
core/apps/evaluation/filters/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
18
core/apps/evaluation/filters/customer.py
Normal file
18
core/apps/evaluation/filters/customer.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from django_filters import rest_framework as filters
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerFilter(filters.FilterSet):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CustomerModel
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyOwnerFilter(filters.FilterSet):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = PropertyOwnerModel
|
||||||
|
fields = []
|
||||||
|
|
||||||
1
core/apps/evaluation/forms/__init__.py
Normal file
1
core/apps/evaluation/forms/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
18
core/apps/evaluation/forms/customer.py
Normal file
18
core/apps/evaluation/forms/customer.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from django import forms
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerForm(forms.ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = CustomerModel
|
||||||
|
fields = "__all__"
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyOwnerForm(forms.ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = PropertyOwnerModel
|
||||||
|
fields = "__all__"
|
||||||
|
|
||||||
42
core/apps/evaluation/migrations/0001_initial.py
Normal file
42
core/apps/evaluation/migrations/0001_initial.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-02-12 10:18
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CustomerModel',
|
||||||
|
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)),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='name')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'CustomerModel',
|
||||||
|
'verbose_name_plural': 'CustomerModels',
|
||||||
|
'db_table': 'Customer',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PropertyownerModel',
|
||||||
|
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)),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='name')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'PropertyownerModel',
|
||||||
|
'verbose_name_plural': 'PropertyownerModels',
|
||||||
|
'db_table': 'PropertyOwner',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-02-12 10:29
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('evaluation', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='customermodel',
|
||||||
|
options={'verbose_name': 'Customer', 'verbose_name_plural': 'Customers'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='propertyownermodel',
|
||||||
|
options={'verbose_name': 'Property Owner', 'verbose_name_plural': 'Property Owners'},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='name',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='name',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='address',
|
||||||
|
field=models.TextField(blank=True, default='', verbose_name='address'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='bank_account',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=30, verbose_name='bank account (HISOB raqam)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='certificate_file',
|
||||||
|
field=models.FileField(blank=True, null=True, upload_to='customers/certificates/', verbose_name='certificate file (guvohnoma)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='customer_type',
|
||||||
|
field=models.CharField(choices=[('legal', 'Yuridik shaxs'), ('individual', 'Jismoniy shaxs')], default=1, max_length=20, verbose_name='customer type'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='director_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='director full name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='first_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='first name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='inn',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=20, verbose_name='INN'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='jshshir',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=14, verbose_name='JSHSHIR'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='last_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='last name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='mfo',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=10, verbose_name='MFO'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='middle_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='middle name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='org_address',
|
||||||
|
field=models.TextField(blank=True, default='', verbose_name='organization address'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='org_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=500, verbose_name='organization name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='passport_issued_by',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='passport issued by'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='passport_issued_date',
|
||||||
|
field=models.DateField(blank=True, null=True, verbose_name='passport issued date'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='passport_number',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=20, verbose_name='passport number'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customermodel',
|
||||||
|
name='passport_series',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=10, verbose_name='passport series'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='address',
|
||||||
|
field=models.TextField(blank=True, default='', verbose_name='address'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='bank_account',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=30, verbose_name='bank account (HISOB raqam)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='certificate_file',
|
||||||
|
field=models.FileField(blank=True, null=True, upload_to='property_owners/certificates/', verbose_name='certificate file (guvohnoma)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='director_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='director full name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='first_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='first name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='inn',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=20, verbose_name='INN'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='jshshir',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=14, verbose_name='JSHSHIR'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='last_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='last name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='mfo',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=10, verbose_name='MFO'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='middle_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='middle name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='org_address',
|
||||||
|
field=models.TextField(blank=True, default='', verbose_name='organization address'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='org_name',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=500, verbose_name='organization name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='owner_type',
|
||||||
|
field=models.CharField(choices=[('legal', 'Yuridik shaxs'), ('individual', 'Jismoniy shaxs')], default=1, max_length=20, verbose_name='owner type'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='passport_issued_by',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=255, verbose_name='passport issued by'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='passport_issued_date',
|
||||||
|
field=models.DateField(blank=True, null=True, verbose_name='passport issued date'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='passport_number',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=20, verbose_name='passport number'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='propertyownermodel',
|
||||||
|
name='passport_series',
|
||||||
|
field=models.CharField(blank=True, default='', max_length=10, verbose_name='passport series'),
|
||||||
|
),
|
||||||
|
migrations.AlterModelTable(
|
||||||
|
name='customermodel',
|
||||||
|
table='customer',
|
||||||
|
),
|
||||||
|
migrations.AlterModelTable(
|
||||||
|
name='propertyownermodel',
|
||||||
|
table='property_owner',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
|
|||||||
167
core/apps/evaluation/models/customer.py
Normal file
167
core/apps/evaluation/models/customer.py
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django_core.models import AbstractBaseModel
|
||||||
|
from model_bakery import baker
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerTypeChoice(models.TextChoices):
|
||||||
|
LEGAL = "legal", _("Yuridik shaxs")
|
||||||
|
INDIVIDUAL = "individual", _("Jismoniy shaxs")
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerModel(AbstractBaseModel):
|
||||||
|
"""Buyurtmachi — baholashga buyurtma beruvchi (yuridik yoki jismoniy shaxs)"""
|
||||||
|
|
||||||
|
customer_type = models.CharField(
|
||||||
|
verbose_name=_("customer type"),
|
||||||
|
max_length=20,
|
||||||
|
choices=CustomerTypeChoice,
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Jismoniy shaxs ma'lumotlari ---
|
||||||
|
jshshir = models.CharField(
|
||||||
|
verbose_name=_("JSHSHIR"), max_length=14, blank=True, default=""
|
||||||
|
) # Kiritiladi
|
||||||
|
passport_series = models.CharField(
|
||||||
|
verbose_name=_("passport series"), max_length=10, blank=True, default=""
|
||||||
|
) # Kiritiladi
|
||||||
|
passport_number = models.CharField(
|
||||||
|
verbose_name=_("passport number"), max_length=20, blank=True, default=""
|
||||||
|
) # Kiritiladi
|
||||||
|
first_name = models.CharField(
|
||||||
|
verbose_name=_("first name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API: JSHSHIR orqali to'ladi
|
||||||
|
last_name = models.CharField(
|
||||||
|
verbose_name=_("last name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API: JSHSHIR orqali to'ladi
|
||||||
|
middle_name = models.CharField(
|
||||||
|
verbose_name=_("middle name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API: JSHSHIR orqali to'ladi
|
||||||
|
address = models.TextField(
|
||||||
|
verbose_name=_("address"), blank=True, default=""
|
||||||
|
) # 🌐 API: JSHSHIR orqali to'ladi
|
||||||
|
passport_issued_date = models.DateField(
|
||||||
|
verbose_name=_("passport issued date"), null=True, blank=True
|
||||||
|
) # 🌐 API
|
||||||
|
passport_issued_by = models.CharField(
|
||||||
|
verbose_name=_("passport issued by"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
|
||||||
|
# --- Yuridik shaxs ma'lumotlari ---
|
||||||
|
inn = models.CharField(
|
||||||
|
verbose_name=_("INN"), max_length=20, blank=True, default=""
|
||||||
|
) # Kiritiladi
|
||||||
|
org_name = models.CharField(
|
||||||
|
verbose_name=_("organization name"), max_length=500, blank=True, default=""
|
||||||
|
) # 🌐 API: INN orqali to'ladi
|
||||||
|
org_address = models.TextField(
|
||||||
|
verbose_name=_("organization address"), blank=True, default=""
|
||||||
|
) # 🌐 API: INN orqali to'ladi
|
||||||
|
director_name = models.CharField(
|
||||||
|
verbose_name=_("director full name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API: INN orqali to'ladi
|
||||||
|
mfo = models.CharField(
|
||||||
|
verbose_name=_("MFO"), max_length=10, blank=True, default=""
|
||||||
|
) # 🌐 API: INN orqali to'ladi
|
||||||
|
bank_account = models.CharField(
|
||||||
|
verbose_name=_("bank account (HISOB raqam)"), max_length=30, blank=True, default=""
|
||||||
|
) # 🌐 API: INN orqali to'ladi
|
||||||
|
certificate_file = models.FileField(
|
||||||
|
verbose_name=_("certificate file (guvohnoma)"),
|
||||||
|
upload_to="customers/certificates/",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
) # Yuridik shaxs guvohnomasi
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.customer_type == CustomerTypeChoice.LEGAL:
|
||||||
|
return self.org_name or str(self.pk)
|
||||||
|
return f"{self.last_name} {self.first_name}" or str(self.pk)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _baker(cls):
|
||||||
|
return baker.make(cls, customer_type=CustomerTypeChoice.INDIVIDUAL)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "customer"
|
||||||
|
verbose_name = _("Customer")
|
||||||
|
verbose_name_plural = _("Customers")
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyOwnerModel(AbstractBaseModel):
|
||||||
|
"""Mulk egasi — agar buyurtmachi va mulk egasi boshqa-boshqa bo'lsa"""
|
||||||
|
|
||||||
|
owner_type = models.CharField(
|
||||||
|
verbose_name=_("owner type"),
|
||||||
|
max_length=20,
|
||||||
|
choices=CustomerTypeChoice,
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Jismoniy shaxs ma'lumotlari ---
|
||||||
|
jshshir = models.CharField(
|
||||||
|
verbose_name=_("JSHSHIR"), max_length=14, blank=True, default=""
|
||||||
|
)
|
||||||
|
passport_series = models.CharField(
|
||||||
|
verbose_name=_("passport series"), max_length=10, blank=True, default=""
|
||||||
|
)
|
||||||
|
passport_number = models.CharField(
|
||||||
|
verbose_name=_("passport number"), max_length=20, blank=True, default=""
|
||||||
|
)
|
||||||
|
first_name = models.CharField(
|
||||||
|
verbose_name=_("first name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
last_name = models.CharField(
|
||||||
|
verbose_name=_("last name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
middle_name = models.CharField(
|
||||||
|
verbose_name=_("middle name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
address = models.TextField(
|
||||||
|
verbose_name=_("address"), blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
passport_issued_date = models.DateField(
|
||||||
|
verbose_name=_("passport issued date"), null=True, blank=True
|
||||||
|
) # 🌐 API
|
||||||
|
passport_issued_by = models.CharField(
|
||||||
|
verbose_name=_("passport issued by"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
|
||||||
|
# --- Yuridik shaxs ma'lumotlari ---
|
||||||
|
inn = models.CharField(
|
||||||
|
verbose_name=_("INN"), max_length=20, blank=True, default=""
|
||||||
|
)
|
||||||
|
org_name = models.CharField(
|
||||||
|
verbose_name=_("organization name"), max_length=500, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
org_address = models.TextField(
|
||||||
|
verbose_name=_("organization address"), blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
director_name = models.CharField(
|
||||||
|
verbose_name=_("director full name"), max_length=255, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
mfo = models.CharField(
|
||||||
|
verbose_name=_("MFO"), max_length=10, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
bank_account = models.CharField(
|
||||||
|
verbose_name=_("bank account (HISOB raqam)"), max_length=30, blank=True, default=""
|
||||||
|
) # 🌐 API
|
||||||
|
certificate_file = models.FileField(
|
||||||
|
verbose_name=_("certificate file (guvohnoma)"),
|
||||||
|
upload_to="property_owners/certificates/",
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.owner_type == CustomerTypeChoice.LEGAL:
|
||||||
|
return self.org_name or str(self.pk)
|
||||||
|
return f"{self.last_name} {self.first_name}" or str(self.pk)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _baker(cls):
|
||||||
|
return baker.make(cls, owner_type=CustomerTypeChoice.INDIVIDUAL)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "property_owner"
|
||||||
|
verbose_name = _("Property Owner")
|
||||||
|
verbose_name_plural = _("Property Owners")
|
||||||
1
core/apps/evaluation/permissions/__init__.py
Normal file
1
core/apps/evaluation/permissions/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
23
core/apps/evaluation/permissions/customer.py
Normal file
23
core/apps/evaluation/permissions/customer.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from rest_framework import permissions
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerPermission(permissions.BasePermission):
|
||||||
|
|
||||||
|
def __init__(self) -> None: ...
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyownerPermission(permissions.BasePermission):
|
||||||
|
|
||||||
|
def __init__(self) -> None: ...
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return True
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
|
|||||||
27
core/apps/evaluation/serializers/customer/Customer.py
Normal file
27
core/apps/evaluation/serializers/customer/Customer.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel
|
||||||
|
|
||||||
|
|
||||||
|
class BaseCustomerSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = CustomerModel
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ListCustomerSerializer(BaseCustomerSerializer):
|
||||||
|
class Meta(BaseCustomerSerializer.Meta): ...
|
||||||
|
|
||||||
|
|
||||||
|
class RetrieveCustomerSerializer(BaseCustomerSerializer):
|
||||||
|
class Meta(BaseCustomerSerializer.Meta): ...
|
||||||
|
|
||||||
|
|
||||||
|
class CreateCustomerSerializer(BaseCustomerSerializer):
|
||||||
|
class Meta(BaseCustomerSerializer.Meta):
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
]
|
||||||
|
|
||||||
27
core/apps/evaluation/serializers/customer/PropertyOwner.py
Normal file
27
core/apps/evaluation/serializers/customer/PropertyOwner.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
class BasePropertyOwnerSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = PropertyOwnerModel
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ListPropertyOwnerSerializer(BasePropertyOwnerSerializer):
|
||||||
|
class Meta(BasePropertyOwnerSerializer.Meta): ...
|
||||||
|
|
||||||
|
|
||||||
|
class RetrievePropertyOwnerSerializer(BasePropertyOwnerSerializer):
|
||||||
|
class Meta(BasePropertyOwnerSerializer.Meta): ...
|
||||||
|
|
||||||
|
|
||||||
|
class CreatePropertyOwnerSerializer(BasePropertyOwnerSerializer):
|
||||||
|
class Meta(BasePropertyOwnerSerializer.Meta):
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
]
|
||||||
|
|
||||||
2
core/apps/evaluation/serializers/customer/__init__.py
Normal file
2
core/apps/evaluation/serializers/customer/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from .Customer import * # noqa
|
||||||
|
from .PropertyOwner import * # noqa
|
||||||
1
core/apps/evaluation/signals/__init__.py
Normal file
1
core/apps/evaluation/signals/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
13
core/apps/evaluation/signals/customer.py
Normal file
13
core/apps/evaluation/signals/customer.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from django.db.models.signals import post_save
|
||||||
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=CustomerModel)
|
||||||
|
def CustomerSignal(sender, instance, created, **kwargs): ...
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=PropertyOwnerModel)
|
||||||
|
def PropertyOwnerSignal(sender, instance, created, **kwargs): ...
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
|
|||||||
2
core/apps/evaluation/tests/customer/__init__.py
Normal file
2
core/apps/evaluation/tests/customer/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from .test_Customer import * # noqa
|
||||||
|
from .test_PropertyOwner import * # noqa
|
||||||
101
core/apps/evaluation/tests/customer/test_Customer.py
Normal file
101
core/apps/evaluation/tests/customer/test_Customer.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import pytest
|
||||||
|
from django.urls import reverse
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def instance(db):
|
||||||
|
return CustomerModel._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("customer-list"),
|
||||||
|
"retrieve": reverse("customer-detail", kwargs={"pk": instance.pk}),
|
||||||
|
"retrieve-not-found": reverse("customer-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
|
||||||
101
core/apps/evaluation/tests/customer/test_PropertyOwner.py
Normal file
101
core/apps/evaluation/tests/customer/test_PropertyOwner.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import pytest
|
||||||
|
from django.urls import reverse
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def instance(db):
|
||||||
|
return PropertyOwnerModel._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("property-owner-list"),
|
||||||
|
"retrieve": reverse("property-owner-detail", kwargs={"pk": instance.pk}),
|
||||||
|
"retrieve-not-found": reverse("property-owner-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
|
||||||
1
core/apps/evaluation/translation/__init__.py
Normal file
1
core/apps/evaluation/translation/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
14
core/apps/evaluation/translation/customer.py
Normal file
14
core/apps/evaluation/translation/customer.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from modeltranslation.translator import TranslationOptions, register
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
|
||||||
|
|
||||||
|
@register(CustomerModel)
|
||||||
|
class CustomerTranslation(TranslationOptions):
|
||||||
|
fields = []
|
||||||
|
|
||||||
|
|
||||||
|
@register(PropertyOwnerModel)
|
||||||
|
class PropertyOwnerTranslation(TranslationOptions):
|
||||||
|
fields = []
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
from django.urls import path, include
|
from django.urls import include, path
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from .views import CustomerView, PropertyOwnerView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
|
router.register("property-owner", PropertyOwnerView, basename="property-owner")
|
||||||
|
router.register("customer", CustomerView, basename="customer")
|
||||||
urlpatterns = [
|
urlpatterns = [path("", include(router.urls))]
|
||||||
path("", include(router.urls)),
|
|
||||||
]
|
|
||||||
|
|||||||
1
core/apps/evaluation/validators/__init__.py
Normal file
1
core/apps/evaluation/validators/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
15
core/apps/evaluation/validators/customer.py
Normal file
15
core/apps/evaluation/validators/customer.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
class CustomerValidator:
|
||||||
|
def __init__(self): ...
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyownerValidator:
|
||||||
|
def __init__(self): ...
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
return True
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from .customer import * # noqa
|
||||||
|
|||||||
43
core/apps/evaluation/views/customer.py
Normal file
43
core/apps/evaluation/views/customer.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
from django_core.mixins import BaseViewSetMixin
|
||||||
|
from drf_spectacular.utils import extend_schema
|
||||||
|
from rest_framework.permissions import AllowAny
|
||||||
|
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||||
|
|
||||||
|
from core.apps.evaluation.models import CustomerModel, PropertyOwnerModel
|
||||||
|
from core.apps.evaluation.serializers.customer import (
|
||||||
|
CreateCustomerSerializer,
|
||||||
|
CreatePropertyOwnerSerializer,
|
||||||
|
ListCustomerSerializer,
|
||||||
|
ListPropertyOwnerSerializer,
|
||||||
|
RetrieveCustomerSerializer,
|
||||||
|
RetrievePropertyOwnerSerializer,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["Customer"])
|
||||||
|
class CustomerView(BaseViewSetMixin, ReadOnlyModelViewSet):
|
||||||
|
queryset = CustomerModel.objects.all()
|
||||||
|
serializer_class = ListCustomerSerializer
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
|
action_permission_classes = {}
|
||||||
|
action_serializer_class = {
|
||||||
|
"list": ListCustomerSerializer,
|
||||||
|
"retrieve": RetrieveCustomerSerializer,
|
||||||
|
"create": CreateCustomerSerializer,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@extend_schema(tags=["PropertyOwner"])
|
||||||
|
class PropertyOwnerView(BaseViewSetMixin, ReadOnlyModelViewSet):
|
||||||
|
queryset = PropertyOwnerModel.objects.all()
|
||||||
|
serializer_class = ListPropertyOwnerSerializer
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
|
||||||
|
action_permission_classes = {}
|
||||||
|
action_serializer_class = {
|
||||||
|
"list": ListPropertyOwnerSerializer,
|
||||||
|
"retrieve": RetrievePropertyOwnerSerializer,
|
||||||
|
"create": CreatePropertyOwnerSerializer,
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user