21 Commits

Author SHA1 Message Date
xoliqberdiyev
7d6618155f change ws response 2026-04-21 14:45:01 +05:00
github-actions[bot]
11605e6e6c 🔄 Update image to 93 [CI SKIP] 2026-04-21 08:07:30 +00:00
komoliddin
8a1a66a05d feat: add Didox service integration for company info retrieval
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 2m9s
2026-04-21 13:05:45 +05:00
github-actions[bot]
70555fa93a 🔄 Update image to 92 [CI SKIP] 2026-04-20 13:12:55 +00:00
674eafe65b Merge pull request 'fix' (#73) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m59s
Reviewed-on: #73
2026-04-20 13:11:20 +00:00
b03d2e1c5e Merge pull request 'add new fields' (#72) from behruz into main
Some checks failed
Deploy to Production / build-and-deploy (push) Failing after 31s
Reviewed-on: #72
2026-04-20 13:06:21 +00:00
github-actions[bot]
c5624e361d 🔄 Update image to 90 [CI SKIP] 2026-04-20 13:02:55 +00:00
c44b08bb28 Merge pull request 'fix' (#71) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m59s
Reviewed-on: #71
2026-04-20 13:01:19 +00:00
github-actions[bot]
0508a49c1d 🔄 Update image to 89 [CI SKIP] 2026-04-20 10:38:57 +00:00
8b97ca53bb Merge pull request 'fix' (#70) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m56s
Reviewed-on: #70
2026-04-20 10:37:24 +00:00
github-actions[bot]
9f7b29fa13 🔄 Update image to 88 [CI SKIP] 2026-04-20 10:35:28 +00:00
b4a3243e9c Merge pull request 'gi' (#69) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m55s
Reviewed-on: #69
2026-04-20 10:33:56 +00:00
github-actions[bot]
3c9438aff6 🔄 Update image to 87 [CI SKIP] 2026-04-20 10:31:42 +00:00
a3c67c5bfb Merge pull request 'remove name_ru and name_en fields' (#68) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m55s
Reviewed-on: #68
2026-04-20 10:30:11 +00:00
github-actions[bot]
a2684ff749 🔄 Update image to 86 [CI SKIP] 2026-04-20 10:27:16 +00:00
91bbb6b6e5 Merge pull request 'change file name' (#67) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m56s
Reviewed-on: #67
2026-04-20 10:25:44 +00:00
github-actions[bot]
ae9f10aa4d 🔄 Update image to 85 [CI SKIP] 2026-04-20 10:16:13 +00:00
f2dc2e1d52 Merge pull request 'add migrations files in shared app' (#66) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m56s
Reviewed-on: #66
2026-04-20 10:14:39 +00:00
github-actions[bot]
10646e2ebf 🔄 Update image to 84 [CI SKIP] 2026-04-20 10:09:49 +00:00
93f6e79f58 Merge pull request 'fix' (#65) from behruz into main
All checks were successful
Deploy to Production / build-and-deploy (push) Successful in 1m57s
Reviewed-on: #65
2026-04-20 10:08:16 +00:00
d1aad04ab8 Merge pull request 'registring region,district and village models' (#64) from behruz into main
Some checks failed
Deploy to Production / build-and-deploy (push) Failing after 51s
Reviewed-on: #64
2026-04-20 10:06:37 +00:00
13 changed files with 124 additions and 26 deletions

View File

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

View File

@@ -9,7 +9,7 @@ import environ
environ.Env.read_env(os.path.join(".env"))
env = environ.Env(
DEBUG=(bool, False),
DEBUG=(bool, True),
CACHE_TIME=(int, 180),
OTP_EXPIRE_TIME=(int, 2),
VITE_LIVE=(bool, False),
@@ -26,4 +26,5 @@ env = environ.Env(
OTP_SERVICE="EskizService",
PROJECT_ENV=(str, "prod"),
SILK_ENABLED=(bool, False),
DIDOX_PARTNER_TOKEN=(str),
)

View File

@@ -49,6 +49,7 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.postgres",
] + APPS
MODULES = [app for app in MODULES if isinstance(app, str)]
@@ -165,6 +166,8 @@ SITE_URL = env.str("SITE_URL", default="http://localhost:8055")
MODELTRANSLATION_LANGUAGES = ("uz", "ru", "en")
MODELTRANSLATION_DEFAULT_LANGUAGE = "uz"
DIDOX_PARTNER_TOKEN = env.str("DIDOX_PARTNER_TOKEN")
JST_LANGUAGES = [

View File

@@ -13,7 +13,7 @@ from config.env import env
def home(request):
return HttpResponse("OK: #503c16bdb81281f1483c938c26a17bbdb9ec6e2a")
return HttpResponse("OK: #8a1a66a05dfdf0a268b2db2da73cc5046266f4c1")
urlpatterns = [

View File

@@ -41,7 +41,7 @@ class ChatConsumer(AsyncWebsocketConsumer):
async def receive(self, text_data):
user = self.scope.get("user")
if not user or isinstance(user, AnonymousUser):
await self.close(code=4001)
await self.close(code=401)
return
try:
@@ -53,13 +53,10 @@ class ChatConsumer(AsyncWebsocketConsumer):
message_type = data.get("message_type", "text")
text = (data.get("text") or "").strip()
# Matn xabari uchun text majburiy
if message_type == "text" and not text:
await self.send(text_data=json.dumps({"error": "Matn bo'sh bo'lishi mumkin emas."}))
return
# WS orqali faqat matn + caption saqlanadi.
# Fayl yuklash uchun REST /chat/messages/ POST ishlatiladi.
if message_type != "text":
await self.send(
text_data=json.dumps(
@@ -68,22 +65,29 @@ class ChatConsumer(AsyncWebsocketConsumer):
)
return
# DB ga saqlash — post_save signal WS ga broadcast qiladi
await self._save_message(user, text)
async def chat_message(self, event):
await self.send(
text_data=json.dumps(
{
"id": event["id"],
"message_type": event["message_type"],
"text": event["text"],
"file_url": event["file_url"],
"sender": event["sender"],
"created_at": event["created_at"],
}
)
)
# Uz
# Bu funksiya ishlatilmayapti, shuning uchun commentga olib qoydim, bu funksiya orniga /core/apps/chat/tasks/message.py ichida rest api yordamida message
# yuborilsa ishlatiladigan task bor.
# En
# This function is not used, so I commented it out. Instead, a task is used in /core/apps/chat/tasks/message.py
# to send message when message is added from REST API.
# async def chat_message(self, event):
# await self.send(
# text_data=json.dumps(
# {
# "id": event["id"],
# "message_type": event["message_type"],
# "text": event["text"],
# "file_url": event["file_url"],
# "sender": event["sender"],
# "created_at": event["created_at"],
# }
# )
# )
@database_sync_to_async
def _save_message(self, user, text):

View File

@@ -78,5 +78,6 @@ class CreateChatmessageSerializer(serializers.ModelSerializer):
request = self.context["request"]
message = super().create(validated_data)
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

View File

@@ -7,7 +7,7 @@ from core.apps.chat.models import ChatmessageModel
@shared_task
def send_message_to_chat(message_id, file_url):
def send_message_to_chat(message_id, file_url, avatar_url):
try:
message = ChatmessageModel.objects.get(id=message_id)
except ChatmessageModel.DoesNotExist:
@@ -24,12 +24,12 @@ def send_message_to_chat(message_id, file_url):
"id": sender_obj.id,
"full_name": full_name,
"role": sender_obj.role,
"phone": sender_obj.phone,
"avatar": avatar_url,
}
else:
sender_data = None
# file_url = request.build_absolute_uri(message.file.url) if message.file else None
async_to_sync(channel_layer.group_send)(
f"chat_room_{message.room_id}",
{

View File

@@ -26,6 +26,7 @@ from .views import (
AutoEvaluationListAppraisersView,
AutoEvaluationSetAppraisersView,
AutoEvaluationRemoveAppraisersView,
DidoxCompanyInfoAPIView,
)
@@ -60,4 +61,9 @@ urlpatterns = [
path("<int:id>/remove/", AutoEvaluationRemoveAppraisersView.as_view(), name="auto-evaluation-remove-appraisers"),
]
)),
path(
"didox/info/<int:tin>/",
DidoxCompanyInfoAPIView.as_view(),
name="didox-info"
),
]

View File

@@ -11,3 +11,4 @@ from .report import * # noqa
from .request import * # noqa
from .valuation import * # noqa
from .vehicle import * # noqa
from .didox import * # noqa

View File

@@ -0,0 +1,51 @@
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import AllowAny
from rest_framework.generics import GenericAPIView
from drf_spectacular.utils import extend_schema, OpenApiParameter
from core.services.didox import DidoxService
class DidoxCompanyInfoAPIView(GenericAPIView):
authentication_classes = []
permission_classes = [AllowAny]
@extend_schema(
tags=["Didox"],
summary="Get company info by TIN",
description="TIN/JSHSHIR orqali Didoxdan ma'lumot olish",
parameters=[
OpenApiParameter(
name="tin",
type=int,
location=OpenApiParameter.PATH,
required=True,
description="TIN / STIR / INN / JSHSHIR"
)
],
responses={200: dict},
)
def get(self, request, *args, **kwargs):
tin = kwargs.get("tin")
# 🔥 TYPE CHECK
try:
tin = int(tin)
except (TypeError, ValueError):
return Response(
{"detail": "TIN must be a valid integer"},
status=status.HTTP_400_BAD_REQUEST
)
data = DidoxService.get_company_info(tin)
if not data:
return Response(
{"detail": "Didox service unavailable"},
status=status.HTTP_502_BAD_GATEWAY
)
return Response(data, status=status.HTTP_200_OK)

View File

@@ -1,3 +1,4 @@
from .otp import * # noqa
from .sms import * # noqa
from .user import * # noqa
from .didox import * # noqa

27
core/services/didox.py Normal file
View File

@@ -0,0 +1,27 @@
import requests
from django.conf import settings
import logging
logger = logging.getLogger(__name__)
class DidoxService:
BASE_URL = "https://testapi3.didox.uz/v1"
@classmethod
def get_company_info(cls, tin: int) -> dict:
url = f"{cls.BASE_URL}/utils/info/{tin}"
headers = {"Partner-Authorization": settings.DIDOX_PARTNER_TOKEN}
try:
response = requests.get(url=url, headers=headers, timeout=15,verify=False)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
logger.exception(f"Didox API error: {str(e)}")
return {}

View File

@@ -84,7 +84,7 @@ services:
max-file: "5"
web:
image: husanjon/sifatbaho:82
image: husanjon/sifatbaho:93
env_file:
- .env
environment:
@@ -129,7 +129,7 @@ services:
max-file: "5"
celery:
image: husanjon/sifatbaho:82
image: husanjon/sifatbaho:93
env_file:
- .env
environment: