Compare commits
30 Commits
406477fc33
...
33aa06f80b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33aa06f80b | ||
|
|
cb2d83b00d | ||
| 46c9621457 | |||
|
|
8d73fa09a7 | ||
| 3367063707 | |||
|
|
ae926914a5 | ||
|
|
229676be5c | ||
| d2f517baf4 | |||
|
|
6df20f35c2 | ||
|
|
fa676bfa96 | ||
| ca9f12ae32 | |||
|
|
56f693abfd | ||
|
|
5049919865 | ||
| ca3c9bfe4a | |||
|
|
8d8744731a | ||
|
|
7ab1e0b1e0 | ||
| f66a35ec80 | |||
|
|
f71dfa50c1 | ||
|
|
f68f34178e | ||
| ab68a6a463 | |||
|
|
d246406384 | ||
| 0a74f71efa | |||
|
|
575364e0ef | ||
|
|
2aa73e15a0 | ||
| 372a289447 | |||
|
|
7343f6191d | ||
|
|
5c4d5fbb71 | ||
| 20043db5b3 | |||
|
|
7d6618155f | ||
|
|
8207b750b8 |
@@ -13,7 +13,7 @@ from config.env import env
|
|||||||
|
|
||||||
|
|
||||||
def home(request):
|
def home(request):
|
||||||
return HttpResponse("OK: #8a1a66a05dfdf0a268b2db2da73cc5046266f4c1")
|
return HttpResponse("OK: #46c96214578b78c1fe731f9a2ceb4429b81d4da9")
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class ChatConsumer(AsyncWebsocketConsumer):
|
|||||||
async def receive(self, text_data):
|
async def receive(self, text_data):
|
||||||
user = self.scope.get("user")
|
user = self.scope.get("user")
|
||||||
if not user or isinstance(user, AnonymousUser):
|
if not user or isinstance(user, AnonymousUser):
|
||||||
await self.close(code=4001)
|
await self.close(code=401)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -53,13 +53,10 @@ class ChatConsumer(AsyncWebsocketConsumer):
|
|||||||
message_type = data.get("message_type", "text")
|
message_type = data.get("message_type", "text")
|
||||||
text = (data.get("text") or "").strip()
|
text = (data.get("text") or "").strip()
|
||||||
|
|
||||||
# Matn xabari uchun text majburiy
|
|
||||||
if message_type == "text" and not text:
|
if message_type == "text" and not text:
|
||||||
await self.send(text_data=json.dumps({"error": "Matn bo'sh bo'lishi mumkin emas."}))
|
await self.send(text_data=json.dumps({"error": "Matn bo'sh bo'lishi mumkin emas."}))
|
||||||
return
|
return
|
||||||
|
|
||||||
# WS orqali faqat matn + caption saqlanadi.
|
|
||||||
# Fayl yuklash uchun REST /chat/messages/ POST ishlatiladi.
|
|
||||||
if message_type != "text":
|
if message_type != "text":
|
||||||
await self.send(
|
await self.send(
|
||||||
text_data=json.dumps(
|
text_data=json.dumps(
|
||||||
@@ -68,9 +65,9 @@ class ChatConsumer(AsyncWebsocketConsumer):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# DB ga saqlash — post_save signal WS ga broadcast qiladi
|
|
||||||
await self._save_message(user, text)
|
await self._save_message(user, text)
|
||||||
|
|
||||||
|
|
||||||
async def chat_message(self, event):
|
async def chat_message(self, event):
|
||||||
await self.send(
|
await self.send(
|
||||||
text_data=json.dumps(
|
text_data=json.dumps(
|
||||||
|
|||||||
@@ -78,5 +78,6 @@ class CreateChatmessageSerializer(serializers.ModelSerializer):
|
|||||||
request = self.context["request"]
|
request = self.context["request"]
|
||||||
message = super().create(validated_data)
|
message = super().create(validated_data)
|
||||||
file_url = request.build_absolute_uri(message.file.url) if message.file else None
|
file_url = request.build_absolute_uri(message.file.url) if message.file else None
|
||||||
send_message_to_chat.delay(message.id, file_url)
|
avatar_url = request.build_absolute_uri(self.context['request'].user.avatar.url) if self.context['request'].user.avatar else None
|
||||||
|
send_message_to_chat.delay(message.id, file_url, avatar_url)
|
||||||
return message
|
return message
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from core.apps.chat.models import ChatmessageModel
|
|||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_message_to_chat(message_id, file_url):
|
def send_message_to_chat(message_id, file_url, avatar_url):
|
||||||
try:
|
try:
|
||||||
message = ChatmessageModel.objects.get(id=message_id)
|
message = ChatmessageModel.objects.get(id=message_id)
|
||||||
except ChatmessageModel.DoesNotExist:
|
except ChatmessageModel.DoesNotExist:
|
||||||
@@ -24,12 +24,12 @@ def send_message_to_chat(message_id, file_url):
|
|||||||
"id": sender_obj.id,
|
"id": sender_obj.id,
|
||||||
"full_name": full_name,
|
"full_name": full_name,
|
||||||
"role": sender_obj.role,
|
"role": sender_obj.role,
|
||||||
|
"phone": sender_obj.phone,
|
||||||
|
"avatar": avatar_url,
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
sender_data = None
|
sender_data = None
|
||||||
|
|
||||||
# file_url = request.build_absolute_uri(message.file.url) if message.file else None
|
|
||||||
|
|
||||||
async_to_sync(channel_layer.group_send)(
|
async_to_sync(channel_layer.group_send)(
|
||||||
f"chat_room_{message.room_id}",
|
f"chat_room_{message.room_id}",
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,15 +50,8 @@ class AutoEvaluationAdmin(ModelAdmin):
|
|||||||
("value_determined", "rate_type"),
|
("value_determined", "rate_type"),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
("Step 3 — Manzil ma'lumotlari", {
|
|
||||||
"fields": (
|
("Step 3 — Avtomobil ma'lumotlari", {
|
||||||
("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": (
|
"fields": (
|
||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
("tex_passport_gived_date", "tex_passport_gived_location"),
|
("tex_passport_gived_date", "tex_passport_gived_location"),
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-04-21 10:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('evaluation', '0030_autoevaluationmodel_evaluation_request'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_city',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_covenience',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_district',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_highways',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_home',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_neighborhood',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_province',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='object_location_street',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='quickevaluationmodel',
|
||||||
|
name='tex_passport_file',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='autoevaluationmodel',
|
||||||
|
name='tex_passport_file',
|
||||||
|
field=models.FileField(blank=True, null=True, upload_to='quick_evaluation/tech_passports/%Y/%m/', verbose_name='tech passport file'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -62,6 +62,13 @@ class AutoEvaluationModel(AbstractBaseModel):
|
|||||||
null=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,
|
||||||
|
)
|
||||||
|
|
||||||
# ── Step 1 — Umumiy ma'lumotlar ──────────────────────────────────
|
# ── Step 1 — Umumiy ma'lumotlar ──────────────────────────────────
|
||||||
registration_number = models.CharField(
|
registration_number = models.CharField(
|
||||||
verbose_name=_("registration number"),
|
verbose_name=_("registration number"),
|
||||||
@@ -180,56 +187,6 @@ class AutoEvaluationModel(AbstractBaseModel):
|
|||||||
related_name='evaluation_auto_rate_type'
|
related_name='evaluation_auto_rate_type'
|
||||||
)
|
)
|
||||||
|
|
||||||
# ── 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 ─────────────────────────────
|
# ── Step 4 — Avtomobil ma'lumotlari ─────────────────────────────
|
||||||
tex_passport_serie_num = models.CharField(
|
tex_passport_serie_num = models.CharField(
|
||||||
verbose_name=_("tech passport series and number"),
|
verbose_name=_("tech passport series and number"),
|
||||||
|
|||||||
@@ -34,12 +34,6 @@ class QuickEvaluationModel(AbstractBaseModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=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 info
|
||||||
car_type = models.CharField(
|
car_type = models.CharField(
|
||||||
|
|||||||
@@ -118,9 +118,8 @@ class EvaluationrequestModel(AbstractBaseModel):
|
|||||||
choices=RequestStatus.choices,
|
choices=RequestStatus.choices,
|
||||||
default=RequestStatus.PENDING,
|
default=RequestStatus.PENDING,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Request #{self.pk} — {self.get_rate_type_display()}"
|
return f"Requests #{self.pk} — {self.get_rate_type_display()}"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _baker(cls):
|
def _baker(cls):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
from core.apps.evaluation.models import AutoEvaluationModel,ReferenceitemModel, EvaluationrequestModel
|
from core.apps.evaluation.models import AutoEvaluationModel,ReferenceitemModel, EvaluationrequestModel
|
||||||
from core.apps.evaluation.serializers.reference import ListReferenceitemSerializer
|
from core.apps.evaluation.serializers.reference import ListReferenceitemSerializer
|
||||||
|
from core.apps.evaluation.choices.request import RequestStatus
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
@@ -33,7 +34,6 @@ class BaseAutoevaluationSerializer(serializers.ModelSerializer):
|
|||||||
"object_owner_legal_inn",
|
"object_owner_legal_inn",
|
||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
"rating_goal",
|
"rating_goal",
|
||||||
"object_location_province",
|
|
||||||
"registration_number",
|
"registration_number",
|
||||||
"object_type",
|
"object_type",
|
||||||
"object_type_display",
|
"object_type_display",
|
||||||
@@ -72,12 +72,12 @@ class ListAutoevaluationSerializer(BaseAutoevaluationSerializer):
|
|||||||
class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
|
class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
|
||||||
car_type_display = serializers.CharField(source="get_car_type_display", read_only=True, default=None)
|
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)
|
car_wheel_display = serializers.CharField(source="get_car_wheel_display", read_only=True, default=None)
|
||||||
object_location_highways_display = serializers.CharField(
|
# object_location_highways_display = serializers.CharField(
|
||||||
source="get_object_location_highways_display", read_only=True, default=None
|
# source="get_object_location_highways_display", read_only=True, default=None
|
||||||
)
|
# )
|
||||||
object_location_covenience_display = serializers.CharField(
|
# object_location_covenience_display = serializers.CharField(
|
||||||
source="get_object_location_covenience_display", read_only=True, default=None
|
# source="get_object_location_covenience_display", read_only=True, default=None
|
||||||
)
|
# )
|
||||||
|
|
||||||
class Meta(BaseAutoevaluationSerializer.Meta):
|
class Meta(BaseAutoevaluationSerializer.Meta):
|
||||||
fields = BaseAutoevaluationSerializer.Meta.fields + [
|
fields = BaseAutoevaluationSerializer.Meta.fields + [
|
||||||
@@ -96,19 +96,9 @@ class RetrieveAutoevaluationSerializer(BaseAutoevaluationSerializer):
|
|||||||
"object_owner_individual_person_passport_num",
|
"object_owner_individual_person_passport_num",
|
||||||
"object_owner_legal_entity",
|
"object_owner_legal_entity",
|
||||||
"object_owner_legal_inn",
|
"object_owner_legal_inn",
|
||||||
# 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
|
# Step 4
|
||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
|
"tex_passport_file",
|
||||||
"tex_passport_gived_date",
|
"tex_passport_gived_date",
|
||||||
"tex_passport_gived_location",
|
"tex_passport_gived_location",
|
||||||
"car_type",
|
"car_type",
|
||||||
@@ -175,16 +165,8 @@ class UpdateAutoevaluationSerializer(serializers.ModelSerializer):
|
|||||||
"form_ownership",
|
"form_ownership",
|
||||||
"value_determined",
|
"value_determined",
|
||||||
"rate_type",
|
"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
|
# Step 4
|
||||||
|
"tex_passport_file",
|
||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
"tex_passport_gived_date",
|
"tex_passport_gived_date",
|
||||||
"tex_passport_gived_location",
|
"tex_passport_gived_location",
|
||||||
@@ -297,17 +279,9 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
|
|||||||
"form_ownership",
|
"form_ownership",
|
||||||
"value_determined",
|
"value_determined",
|
||||||
"rate_type",
|
"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
|
# Step 4
|
||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
|
"tex_passport_file",
|
||||||
"tex_passport_gived_date",
|
"tex_passport_gived_date",
|
||||||
"tex_passport_gived_location",
|
"tex_passport_gived_location",
|
||||||
"car_type",
|
"car_type",
|
||||||
@@ -364,6 +338,10 @@ class CreateAutoevaluationSerializer(serializers.ModelSerializer):
|
|||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
user = self.context.get('request').user
|
user = self.context.get('request').user
|
||||||
validated_data['user'] = user
|
validated_data['user'] = user
|
||||||
|
evaluation_req = validated_data.get("evaluation_request")
|
||||||
|
if evaluation_req:
|
||||||
|
evaluation_req.status = RequestStatus.IN_PROGRESS
|
||||||
|
evaluation_req.save()
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ class RetrieveQuickevaluationSerializer(BaseQuickevaluationSerializer):
|
|||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
"tech_passport_issued_date",
|
"tech_passport_issued_date",
|
||||||
"tech_passport_issued_place",
|
"tech_passport_issued_place",
|
||||||
"tex_passport_file",
|
|
||||||
"car_position",
|
"car_position",
|
||||||
"car_position_name",
|
"car_position_name",
|
||||||
"distance_covered",
|
"distance_covered",
|
||||||
@@ -76,7 +75,6 @@ class CreateQuickevaluationSerializer(serializers.ModelSerializer):
|
|||||||
"tex_passport_serie_num",
|
"tex_passport_serie_num",
|
||||||
"tech_passport_issued_date",
|
"tech_passport_issued_date",
|
||||||
"tech_passport_issued_place",
|
"tech_passport_issued_place",
|
||||||
"tex_passport_file",
|
|
||||||
"car_type",
|
"car_type",
|
||||||
"brand",
|
"brand",
|
||||||
"marka",
|
"marka",
|
||||||
|
|||||||
@@ -33,18 +33,27 @@ class TechPassportAPIView(GenericAPIView):
|
|||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
serializer = TechPassportSerializer(data=request.data)
|
serializer = TechPassportSerializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
data = serializer.validated_data
|
data = serializer.validated_data
|
||||||
|
|
||||||
try:
|
result = TechPassportService.get_auto_info(
|
||||||
result = TechPassportService.get_auto_info(
|
autonumber=data["autonumber"],
|
||||||
autonumber=data["autonumber"],
|
tech_pass_number=data["tech_pass_number"],
|
||||||
tech_pass_number=data["tech_pass_number"],
|
tech_pass_series=data["tech_pass_series"],
|
||||||
tech_pass_series=data["tech_pass_series"],
|
)
|
||||||
)
|
|
||||||
return Response(result, status=status.HTTP_200_OK)
|
|
||||||
|
|
||||||
except Exception as e:
|
response_data = result["data"]
|
||||||
|
status_code = result["status_code"]
|
||||||
|
|
||||||
|
# success bo‘lsa faqat data ichidagi data qaytariladi
|
||||||
|
if status_code == 200:
|
||||||
return Response(
|
return Response(
|
||||||
{"detail": str(e)},
|
response_data.get("data", {}),
|
||||||
status=status.HTTP_400_BAD_REQUEST
|
status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# error bo‘lsa original response qaytariladi
|
||||||
|
return Response(
|
||||||
|
response_data,
|
||||||
|
status=status_code
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2026-04-21 09:48
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('shared', '0003_regionmodel_districtmodel_villagemodel'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='districtmodel',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=255),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='regionmodel',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=255),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='villagemodel',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=255),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -3,7 +3,7 @@ from django_core.models import AbstractBaseModel
|
|||||||
|
|
||||||
|
|
||||||
class RegionModel(AbstractBaseModel):
|
class RegionModel(AbstractBaseModel):
|
||||||
name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Region"
|
verbose_name = "Region"
|
||||||
@@ -11,7 +11,7 @@ class RegionModel(AbstractBaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class DistrictModel(AbstractBaseModel):
|
class DistrictModel(AbstractBaseModel):
|
||||||
name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255)
|
||||||
region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
region = models.ForeignKey(RegionModel, on_delete=models.CASCADE, related_name='districts')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -20,7 +20,7 @@ class DistrictModel(AbstractBaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class VillageModel(AbstractBaseModel):
|
class VillageModel(AbstractBaseModel):
|
||||||
name = models.CharField(max_length=255, unique=True)
|
name = models.CharField(max_length=255)
|
||||||
district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
district = models.ForeignKey(DistrictModel, on_delete=models.CASCADE, related_name='villages')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -1,10 +1,28 @@
|
|||||||
from rest_framework import generics
|
from rest_framework import generics
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from drf_spectacular.utils import extend_schema, OpenApiParameter
|
||||||
|
from drf_spectacular.types import OpenApiTypes
|
||||||
|
|
||||||
from core.apps.shared.serializers.region.district import DistrictSerializer, VillageSerializer, RegionSerializer
|
from core.apps.shared.serializers.region.district import DistrictSerializer, VillageSerializer, RegionSerializer
|
||||||
from core.apps.shared.models import RegionModel, VillageModel, DistrictModel
|
from core.apps.shared.models import RegionModel, VillageModel, DistrictModel
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
parameters=[
|
||||||
|
OpenApiParameter(
|
||||||
|
name="region",
|
||||||
|
type=OpenApiTypes.INT,
|
||||||
|
location=OpenApiParameter.QUERY,
|
||||||
|
description="Filter by region ID"
|
||||||
|
),
|
||||||
|
OpenApiParameter(
|
||||||
|
name="name",
|
||||||
|
type=OpenApiTypes.STR,
|
||||||
|
location=OpenApiParameter.QUERY,
|
||||||
|
description="Filter by district name"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
class DistrictListCreateView(generics.ListCreateAPIView):
|
class DistrictListCreateView(generics.ListCreateAPIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
serializer_class = DistrictSerializer
|
serializer_class = DistrictSerializer
|
||||||
@@ -19,7 +37,22 @@ class DistrictListCreateView(generics.ListCreateAPIView):
|
|||||||
return self.queryset.filter(region=region)
|
return self.queryset.filter(region=region)
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
parameters=[
|
||||||
|
OpenApiParameter(
|
||||||
|
name="district",
|
||||||
|
type=OpenApiTypes.INT,
|
||||||
|
location=OpenApiParameter.QUERY,
|
||||||
|
description="Filter by district ID"
|
||||||
|
),
|
||||||
|
OpenApiParameter(
|
||||||
|
name="name",
|
||||||
|
type=OpenApiTypes.STR,
|
||||||
|
location=OpenApiParameter.QUERY,
|
||||||
|
description="Filter by village name"
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
class VillageListCreateView(generics.ListCreateAPIView):
|
class VillageListCreateView(generics.ListCreateAPIView):
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
serializer_class = VillageSerializer
|
serializer_class = VillageSerializer
|
||||||
|
|||||||
@@ -44,21 +44,28 @@ class TechPassportService:
|
|||||||
verify=False
|
verify=False
|
||||||
)
|
)
|
||||||
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Tech passport info fetched successfully: {response.status_code}"
|
f"Tech passport response status: {response.status_code}"
|
||||||
)
|
)
|
||||||
|
|
||||||
response_data = response.json()
|
try:
|
||||||
|
response_data = response.json()
|
||||||
|
except ValueError:
|
||||||
|
response_data = {
|
||||||
|
"detail": "Invalid response from external service"
|
||||||
|
}
|
||||||
|
|
||||||
return response_data.get("data", {})
|
return {
|
||||||
|
"status_code": response.status_code,
|
||||||
|
"data": response_data
|
||||||
|
}
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
logger.error(
|
logger.error(str(e))
|
||||||
f"Error while fetching tech passport info: {str(e)}"
|
|
||||||
)
|
|
||||||
return {
|
return {
|
||||||
"success": False,
|
"status_code": 500,
|
||||||
"message": str(e)
|
"data": {
|
||||||
|
"detail": str(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ services:
|
|||||||
max-file: "5"
|
max-file: "5"
|
||||||
|
|
||||||
web:
|
web:
|
||||||
image: husanjon/sifatbaho:93
|
image: husanjon/sifatbaho:103
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
@@ -129,7 +129,7 @@ services:
|
|||||||
max-file: "5"
|
max-file: "5"
|
||||||
|
|
||||||
celery:
|
celery:
|
||||||
image: husanjon/sifatbaho:93
|
image: husanjon/sifatbaho:103
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Reference in New Issue
Block a user