Compare commits
10 Commits
f24a2760a9
...
f293cc7018
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f293cc7018 | ||
|
|
445ae78095 | ||
|
|
b924442631 | ||
|
|
479d8b8faa | ||
|
|
07d7e8604f | ||
|
|
ae8a14b83c | ||
|
|
78746e6071 | ||
|
|
824ad25a17 | ||
|
|
e26ab5eea6 | ||
|
|
eb010cb6de |
@@ -12,7 +12,7 @@ class DistributedProductListSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = DistributedProduct
|
||||
fields = [
|
||||
'id', 'product', 'quantity', 'employee_name', 'quantity', 'user', 'created_at'
|
||||
'id', 'product', 'quantity', 'employee_name', 'quantity', 'user', 'created_at', 'date'
|
||||
]
|
||||
|
||||
def get_user(self, obj):
|
||||
|
||||
@@ -36,6 +36,8 @@ class DistrictCreateSerializer(serializers.Serializer):
|
||||
if not user:
|
||||
raise serializers.ValidationError({"user_id": "Foydalanuvchi topilmadi"})
|
||||
data['user'] = user
|
||||
if District.objects.filter(name=data['name'], user=user).exists():
|
||||
raise serializers.ValidationError({'name': "District qo'shib bolmadi"})
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
|
||||
7
core/apps/dashboard/serializers/send_message.py
Normal file
7
core/apps/dashboard/serializers/send_message.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# rest framework
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class SendMessageSerializer(serializers.Serializer):
|
||||
user_ids = serializers.ListField(child=serializers.IntegerField())
|
||||
message = serializers.CharField()
|
||||
@@ -19,7 +19,7 @@ class SupportListSerializer(serializers.ModelSerializer):
|
||||
return {
|
||||
'id': obj.district.id,
|
||||
'name': obj.district.name,
|
||||
}
|
||||
} if obj.district else None
|
||||
|
||||
def get_user(self, obj):
|
||||
return {
|
||||
|
||||
@@ -35,6 +35,8 @@ from core.apps.dashboard.views.location import LocationViewSet, UserLocationView
|
||||
from core.apps.dashboard.views.support import SupportListApiView
|
||||
# distibuted products
|
||||
from core.apps.dashboard.views.dis_prod import DistributedProductListApiView
|
||||
# send message
|
||||
from core.apps.dashboard.views.send_message import SendMessageToEmployee
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
@@ -82,7 +84,10 @@ urlpatterns = [
|
||||
[
|
||||
path('list/', DistributedProductListApiView.as_view(), name='distributed-product-list-api'),
|
||||
]
|
||||
))
|
||||
)),
|
||||
|
||||
# -------------- send message --------------
|
||||
path('send_message/', SendMessageToEmployee.as_view()),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -75,6 +75,13 @@ class DoctorViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
name='user_id',
|
||||
description="user id bo'yicha filter",
|
||||
required=False,
|
||||
)
|
||||
],
|
||||
operation_description="Shifokorlar ro'yxatini olish",
|
||||
operation_summary="Shifokolar ro'yxati",
|
||||
@@ -147,6 +154,8 @@ class DoctorViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
work_place = request.query_params.get('work_place', None)
|
||||
sphere = request.query_params.get('sphere', None)
|
||||
user_full_name = request.query_params.get('user', None)
|
||||
user_id = request.query_params.get('user_id', None)
|
||||
|
||||
|
||||
queryset = self.queryset.all()
|
||||
|
||||
@@ -177,6 +186,8 @@ class DoctorViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
Q(user__first_name__istartswith=user_full_name) |
|
||||
Q(user__last_name__istartswith=user_full_name)
|
||||
)
|
||||
if not user_id is None:
|
||||
queryset = queryset.filter(user__id=user_id)
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
|
||||
@@ -60,6 +60,13 @@ class PharmacyViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
name='user_id',
|
||||
description="user id bo'yicha filter",
|
||||
required=False,
|
||||
)
|
||||
],
|
||||
)
|
||||
@action(detail=False, methods=['get'], url_path="list")
|
||||
@@ -70,6 +77,7 @@ class PharmacyViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
place_name = request.query_params.get('place', None)
|
||||
district_name = request.query_params.get('district', None)
|
||||
user_full_name = request.query_params.get('user', None)
|
||||
user_id = request.query_params.get('user_id', None)
|
||||
|
||||
queryset = self.queryset.all()
|
||||
|
||||
@@ -88,6 +96,9 @@ class PharmacyViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
Q(user__first_name__istartswith=user_full_name) |
|
||||
Q(user__last_name__istartswith=user_full_name)
|
||||
)
|
||||
if not user_id is None:
|
||||
queryset = queryset.filter(user__id=user_id)
|
||||
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
|
||||
@@ -53,6 +53,13 @@ class PlaceViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
name='user_id',
|
||||
description="user id bo'yicha filter",
|
||||
required=False,
|
||||
)
|
||||
],
|
||||
)
|
||||
@action(detail=False, methods=['get'], url_path="list")
|
||||
@@ -62,6 +69,7 @@ class PlaceViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
name = request.query_params.get('name', None)
|
||||
district_name = request.query_params.get('district', None)
|
||||
user_full_name = request.query_params.get('user', None)
|
||||
user_id = request.query_params.get('user_id', None)
|
||||
|
||||
queryset = self.queryset.all()
|
||||
|
||||
@@ -77,6 +85,9 @@ class PlaceViewSet(viewsets.GenericViewSet, ResponseMixin):
|
||||
Q(user__first_name__istartswith=user_full_name) |
|
||||
Q(user__last_name__istartswith=user_full_name)
|
||||
)
|
||||
if not user_id is None:
|
||||
queryset = queryset.filter(user__id=user_id)
|
||||
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
|
||||
38
core/apps/dashboard/views/send_message.py
Normal file
38
core/apps/dashboard/views/send_message.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# rest framework
|
||||
from rest_framework import generics, permissions
|
||||
|
||||
|
||||
# services
|
||||
from core.services.send_telegram_msg import send_message
|
||||
# accounts
|
||||
from core.apps.accounts.models import User
|
||||
#shared
|
||||
from core.apps.shared.utils.response_mixin import ResponseMixin
|
||||
# dashboard
|
||||
from core.apps.dashboard.serializers.send_message import SendMessageSerializer
|
||||
|
||||
|
||||
class SendMessageToEmployee(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = SendMessageSerializer
|
||||
permission_classes = [permissions.IsAdminUser]
|
||||
queryset = User.objects.all()
|
||||
|
||||
def post(self, request):
|
||||
try:
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
data = serializer.validated_data
|
||||
message = data.get('message')
|
||||
user_ids = data.get('user_ids')
|
||||
users = User.objects.filter(id__in=user_ids)
|
||||
for user in users:
|
||||
send_message(chat_id=user.telegram_id, message=message)
|
||||
return self.success_response(
|
||||
data={},
|
||||
message="Xabar yuborildi"
|
||||
)
|
||||
except Exception as e:
|
||||
return self.error_response(
|
||||
data=str(e),
|
||||
message="xatolik, backend dasturchi bilan boglaning"
|
||||
)
|
||||
@@ -19,6 +19,7 @@ urlpatterns = [
|
||||
path('list/', order_view.OrderListApiView.as_view(), name='order-list-api'),
|
||||
path('create/', order_view.OrderCreateApiView.as_view(), name='order-create-api'),
|
||||
path('<int:id>/update/', order_view.OrderUpdateApiView.as_view(), name='order-update-api'),
|
||||
path('<int:id>/send_pdf/', order_view.SendFileToTelegramApiView.as_view(), name='order-send-pdf-api'),
|
||||
]
|
||||
)),
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
# rest framework
|
||||
from rest_framework import generics, permissions
|
||||
from rest_framework import generics, permissions, views
|
||||
|
||||
# drf yasg
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
@@ -14,6 +14,9 @@ from core.apps.orders.serializers.order import OrderCreateSerializer, OrderListS
|
||||
from core.apps.shared.utils.response_mixin import ResponseMixin
|
||||
from core.apps.shared.serializers.base import BaseResponseSerializer, SuccessResponseSerializer
|
||||
|
||||
# services
|
||||
from core.services.send_telegram_msg import send_to_telegram
|
||||
|
||||
|
||||
class OrderCreateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = OrderCreateSerializer
|
||||
@@ -93,4 +96,28 @@ class OrderUpdateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return self.error_response(data=str(e), message='xatolik')
|
||||
return self.error_response(data=str(e), message='xatolik')
|
||||
|
||||
|
||||
|
||||
class SendFileToTelegramApiView(views.APIView, ResponseMixin):
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def get(self, request, id):
|
||||
try:
|
||||
order = Order.objects.filter(id=id).first()
|
||||
if not order:
|
||||
return self.failure_response(
|
||||
data={},
|
||||
message="Order not found"
|
||||
)
|
||||
send_to_telegram(request.user.telegram_id, order.id)
|
||||
return self.success_response(
|
||||
data={},
|
||||
message='Succefully send!'
|
||||
)
|
||||
except Exception as e:
|
||||
return self.error_response(
|
||||
data=str(e),
|
||||
message="xatolik, backend dasturchiga murojaat qiling"
|
||||
)
|
||||
|
||||
19
core/apps/shared/migrations/0017_alter_support_district.py
Normal file
19
core/apps/shared/migrations/0017_alter_support_district.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.2 on 2025-12-04 12:35
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('shared', '0016_plan_comment_plan_doctor_plan_extra_location_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='support',
|
||||
name='district',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supports', to='shared.district'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.2 on 2025-12-11 13:15
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('shared', '0017_alter_support_district'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='district',
|
||||
unique_together={('user', 'name')},
|
||||
),
|
||||
]
|
||||
@@ -14,3 +14,6 @@ class District(BaseModel):
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
unique_together = ('user', 'name')
|
||||
@@ -13,7 +13,13 @@ class Support(BaseModel):
|
||||
('HELP', 'yordam'),
|
||||
)
|
||||
|
||||
district = models.ForeignKey(District, on_delete=models.CASCADE, related_name='supports')
|
||||
district = models.ForeignKey(
|
||||
District,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='supports',
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
problem = models.TextField()
|
||||
date = models.DateField()
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='supports')
|
||||
|
||||
24
core/apps/shared/serializers/dis_product.py
Normal file
24
core/apps/shared/serializers/dis_product.py
Normal file
@@ -0,0 +1,24 @@
|
||||
# rest framework
|
||||
from rest_framework import serializers
|
||||
|
||||
# orders
|
||||
from core.apps.orders.models import DistributedProduct
|
||||
|
||||
|
||||
class DistributedProductListSerializer(serializers.ModelSerializer):
|
||||
product = serializers.SerializerMethodField(method_name='get_product')
|
||||
|
||||
class Meta:
|
||||
model = DistributedProduct
|
||||
fields = [
|
||||
'id', 'product', 'quantity', 'employee_name', 'quantity', 'created_at', 'date'
|
||||
]
|
||||
ref_name = "DisProductListSerializer"
|
||||
|
||||
def get_product(self, obj):
|
||||
return {
|
||||
"id": obj.product.id,
|
||||
"name": obj.product.name,
|
||||
"price": obj.product.price,
|
||||
}
|
||||
|
||||
@@ -9,16 +9,17 @@ from core.apps.shared.models import Support, District
|
||||
|
||||
|
||||
class SupportCreateSerializer(serializers.Serializer):
|
||||
district_id = serializers.IntegerField()
|
||||
district_id = serializers.IntegerField(required=False)
|
||||
problem = serializers.CharField()
|
||||
date = serializers.DateField()
|
||||
type = serializers.ChoiceField(choices=Support.TYPE)
|
||||
|
||||
def validate(self, data):
|
||||
district = District.objects.filter(id=data['district_id']).first()
|
||||
if not district:
|
||||
raise serializers.ValidationError({'district': "district not found"})
|
||||
data['district'] = district
|
||||
if data.get('district_id'):
|
||||
district = District.objects.filter(id=data['district_id']).first()
|
||||
if not district:
|
||||
raise serializers.ValidationError({'district': "district not found"})
|
||||
data['district'] = district
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
@@ -30,3 +31,21 @@ class SupportCreateSerializer(serializers.Serializer):
|
||||
type=validated_data.get('type'),
|
||||
problem=validated_data.get('problem' )
|
||||
)
|
||||
|
||||
|
||||
class SupportListSerializer(serializers.ModelSerializer):
|
||||
district = serializers.SerializerMethodField(method_name='get_district')
|
||||
|
||||
class Meta:
|
||||
model = Support
|
||||
fields = [
|
||||
'id', 'problem', 'date', 'type', 'district', 'created_at'
|
||||
]
|
||||
ref_name = "SupportListSerializerForUser"
|
||||
|
||||
def get_district(self, obj):
|
||||
return {
|
||||
'id': obj.district.id,
|
||||
'name': obj.district.name,
|
||||
} if obj.district else None
|
||||
|
||||
@@ -20,6 +20,8 @@ from core.apps.shared.views import tour_plan as tp_view
|
||||
from core.apps.shared.views import factory as factory_view
|
||||
# shared support view
|
||||
from core.apps.shared.views import support as support_view
|
||||
# shared dis product
|
||||
from core.apps.shared.views import dis_product as dp_view
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
@@ -88,6 +90,12 @@ urlpatterns = [
|
||||
path('support/', include(
|
||||
[
|
||||
path('send/', support_view.SupportCreateApiView.as_view(), name='support-create-api'),
|
||||
path('list/', support_view.SupportListApiView.as_view(), name='support-list-api'),
|
||||
]
|
||||
))
|
||||
)),
|
||||
path('distributed_product/', include(
|
||||
[
|
||||
path('list/', dp_view.DistributedProductListApiView.as_view()),
|
||||
]
|
||||
)),
|
||||
]
|
||||
75
core/apps/shared/views/dis_product.py
Normal file
75
core/apps/shared/views/dis_product.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# django
|
||||
from django.db.models import Q
|
||||
|
||||
# rest framework
|
||||
from rest_framework import generics, permissions
|
||||
|
||||
# drf yasg
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
|
||||
# orders
|
||||
from core.apps.orders.models import DistributedProduct
|
||||
|
||||
# shared
|
||||
from core.apps.shared.utils.response_mixin import ResponseMixin
|
||||
|
||||
# dashboard
|
||||
from core.apps.shared.serializers.dis_product import DistributedProductListSerializer
|
||||
|
||||
|
||||
class DistributedProductListApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = DistributedProductListSerializer
|
||||
queryset = DistributedProduct.objects.all()
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
@swagger_auto_schema(
|
||||
manual_parameters=[
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
name="product",
|
||||
description="product name bo'yicha filter",
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
name="date",
|
||||
description="date bo'yicha qidirish",
|
||||
required=False,
|
||||
type=openapi.FORMAT_DATE,
|
||||
),
|
||||
],
|
||||
)
|
||||
def get(self, request):
|
||||
try:
|
||||
product_name = request.query_params.get('product', None)
|
||||
date = request.query_params.get('date', None)
|
||||
|
||||
queryset = self.queryset.filter(user=request.user)
|
||||
|
||||
# filters
|
||||
if product_name is not None:
|
||||
queryset = queryset.filter(product__name__istartswith=product_name)
|
||||
|
||||
if date is not None:
|
||||
queryset = queryset.filter(date=date)
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return self.success_response(
|
||||
data=self.get_paginated_response(serializer.data).data,
|
||||
message="Malumotlar fetch qilindi",
|
||||
)
|
||||
serializer = self.serializer_class(queryset, many=True)
|
||||
return self.success_response(
|
||||
data=serializer.data,
|
||||
message='Malumotlar fetch qilindi'
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return self.error_response(
|
||||
data=str(e),
|
||||
message='xatolik, iltimos backend dasturchiga murojaat qiling'
|
||||
)
|
||||
@@ -53,6 +53,9 @@ class DistrictCreateApiView(generics.CreateAPIView, ResponseMixin):
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
name = serializer.validated_data.get('name')
|
||||
if District.objects.filter(name=name, user=request.user).exists():
|
||||
return self.failure_response(message="District qo'shib bolmadi")
|
||||
|
||||
obj = District.objects.create(name=name, user=request.user)
|
||||
return self.success_response(
|
||||
data=district_serializers.DistrictSerializer(obj).data,
|
||||
|
||||
@@ -8,7 +8,7 @@ from drf_yasg.utils import swagger_auto_schema
|
||||
# shared
|
||||
from core.apps.shared.models import Support
|
||||
from core.apps.shared.utils.response_mixin import ResponseMixin
|
||||
from core.apps.shared.serializers.support import SupportCreateSerializer
|
||||
from core.apps.shared.serializers.support import SupportCreateSerializer, SupportListSerializer
|
||||
|
||||
|
||||
class SupportCreateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
@@ -34,4 +34,72 @@ class SupportCreateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
return self.error_response(
|
||||
data=str(e),
|
||||
message='xatolik, backend dastruchiga murojaat qiling iltimos'
|
||||
)
|
||||
|
||||
|
||||
class SupportListApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = SupportListSerializer
|
||||
queryset = Support.objects.all()
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
@swagger_auto_schema(
|
||||
manual_parameters=[
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
name="problem",
|
||||
description="problem text bo'yicha filter",
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
name="district",
|
||||
description="tuman name bo'yicha filter",
|
||||
required=False,
|
||||
type=openapi.TYPE_STRING,
|
||||
),
|
||||
openapi.Parameter(
|
||||
in_=openapi.IN_QUERY,
|
||||
name="date",
|
||||
description="date bo'yicha qidirish",
|
||||
required=False,
|
||||
type=openapi.FORMAT_DATE,
|
||||
),
|
||||
],
|
||||
)
|
||||
def get(self, request):
|
||||
try:
|
||||
problem = request.query_params.get('problem', None)
|
||||
district_name = request.query_params.get('district', None)
|
||||
date = request.query_params.get('date', None)
|
||||
|
||||
queryset = self.queryset.filter(user=request.user)
|
||||
|
||||
# filters
|
||||
if problem is not None:
|
||||
queryset = queryset.filter(problem__istartswith=problem)
|
||||
|
||||
if district_name is not None:
|
||||
queryset = queryset.filter(district__name__istartswith=district_name)
|
||||
|
||||
if date is not None:
|
||||
queryset = queryset.filter(date=date)
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
serializer = self.serializer_class(page, many=True)
|
||||
return self.success_response(
|
||||
data=self.get_paginated_response(serializer.data).data,
|
||||
message="Malumotlar fetch qilindi",
|
||||
)
|
||||
serializer = self.serializer_class(queryset, many=True)
|
||||
return self.success_response(
|
||||
data=serializer.data,
|
||||
message='Malumotlar fetch qilindi'
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return self.error_response(
|
||||
data=str(e),
|
||||
message='xatolik, iltimos backend dasturchiga murojaat qiling'
|
||||
)
|
||||
58
core/bot/main.py
Normal file
58
core/bot/main.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# python
|
||||
import asyncio, logging, sys, os
|
||||
import django
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.base')
|
||||
django.setup()
|
||||
|
||||
# aiogram
|
||||
from aiogram import Bot, Dispatcher, types, filters
|
||||
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo
|
||||
|
||||
# django
|
||||
from django.conf import settings
|
||||
|
||||
TOKEN = settings.BOT_TOKEN
|
||||
|
||||
bot = Bot(token=TOKEN)
|
||||
dp = Dispatcher()
|
||||
|
||||
|
||||
@dp.message(filters.CommandStart)
|
||||
async def start_handler(message: types.Message):
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text="Tizimga kirish",
|
||||
web_app=WebAppInfo(url="https://bot.meridynpharma.com")
|
||||
)]
|
||||
],
|
||||
)
|
||||
text = """
|
||||
🔐 MeridynPharma ish tizimiga kirish
|
||||
|
||||
Hurmatli xodim,
|
||||
MeridynPharma’ning ichki ish jarayonlarini avtomatlashtirish va kunlik faoliyatni samarali boshqarish uchun mo‘ljallangan Rasmiy Xodimlar Mini-Ilovasiga xush kelibsiz.
|
||||
|
||||
Ushbu platforma orqali sizga biriktirilgan vazifalar, hisobotlar, inventarizatsiya jarayonlari va ichki eslatmalar yagona tizim orqali boshqariladi.
|
||||
|
||||
▶️ Tizimga kirish tartibi
|
||||
|
||||
Ish faoliyatini boshlash uchun quyidagi bosqichni bajaring:
|
||||
|
||||
1. Quyida joylashgan “Tizimga kirish” tugmasini bosing.
|
||||
yoki
|
||||
2. Mini-Ilova ochilgandan so‘ng, mini ilova pastki qismida joylashgan tizimga kirish degan tugmani bosing
|
||||
|
||||
Agar mini-app avtomatik ochilmasa, iltimos, tugmani yana bir bor bosing.
|
||||
"""
|
||||
await message.answer(text, reply_markup=keyboard)
|
||||
|
||||
|
||||
async def main():
|
||||
await dp.start_polling(bot)
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
|
||||
asyncio.run(main())
|
||||
@@ -30,4 +30,21 @@ def send_to_telegram(chat_id, order_id):
|
||||
|
||||
except Exception as e:
|
||||
print(f"Telegram xatolik: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def send_message(chat_id, message):
|
||||
bot_token = settings.BOT_TOKEN
|
||||
|
||||
try:
|
||||
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
||||
data = {
|
||||
"chat_id": chat_id,
|
||||
"text": message
|
||||
}
|
||||
response = requests.post(url, data=data)
|
||||
print(response.json())
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Telegram xatosi: {e}")
|
||||
return False
|
||||
@@ -1,3 +1,9 @@
|
||||
aiofiles==25.1.0
|
||||
aiogram==3.23.0
|
||||
aiohappyeyeballs==2.6.1
|
||||
aiohttp==3.13.2
|
||||
aiosignal==1.4.0
|
||||
annotated-types==0.7.0
|
||||
asgiref==3.11.0
|
||||
attrs==25.4.0
|
||||
autobahn==25.11.1
|
||||
@@ -22,20 +28,26 @@ djangorestframework==3.16.1
|
||||
djangorestframework_simplejwt==5.5.1
|
||||
drf-yasg==1.21.11
|
||||
fonttools==4.60.1
|
||||
frozenlist==1.8.0
|
||||
gunicorn==23.0.0
|
||||
h11==0.16.0
|
||||
hyperlink==21.0.0
|
||||
idna==3.11
|
||||
Incremental==24.11.0
|
||||
inflection==0.5.1
|
||||
magic-filter==1.0.12
|
||||
msgpack==1.1.2
|
||||
multidict==6.7.0
|
||||
packaging==25.0
|
||||
pillow==12.0.0
|
||||
propcache==0.4.1
|
||||
psycopg2-binary==2.9.11
|
||||
py-ubjson==0.16.1
|
||||
pyasn1==0.6.1
|
||||
pyasn1_modules==0.4.2
|
||||
pycparser==2.23
|
||||
pydantic==2.12.5
|
||||
pydantic_core==2.41.5
|
||||
pydyf==0.11.0
|
||||
PyJWT==2.10.1
|
||||
pyOpenSSL==25.3.0
|
||||
@@ -51,6 +63,7 @@ tinycss2==1.5.1
|
||||
tinyhtml5==2.0.0
|
||||
Twisted==25.5.0
|
||||
txaio==25.9.2
|
||||
typing-inspection==0.4.2
|
||||
typing_extensions==4.15.0
|
||||
ujson==5.11.0
|
||||
uritemplate==4.2.0
|
||||
@@ -58,6 +71,6 @@ urllib3==2.5.0
|
||||
uvicorn==0.38.0
|
||||
weasyprint==66.0
|
||||
webencodings==0.5.1
|
||||
yarl==1.22.0
|
||||
zope.interface==8.1.1
|
||||
zopfli==0.4.0
|
||||
websockets
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
python3 manage.py collectstatic --noinput
|
||||
python3 manage.py migrate --noinput
|
||||
|
||||
gunicorn config.wsgi:application -b 0.0.0.0:8000 --workers $(($(nproc) * 2 + 1))
|
||||
gunicorn config.wsgi:application -b 0.0.0.0:8000 --workers $(($(nproc) * 2 + 1)) &
|
||||
|
||||
python3 core/bot/main.py &
|
||||
|
||||
wait
|
||||
|
||||
exit $?
|
||||
@@ -2,6 +2,10 @@
|
||||
python3 manage.py collectstatic --noinput
|
||||
python3 manage.py migrate --noinput
|
||||
|
||||
uvicorn config.asgi:application --host 0.0.0.0 --port 8000 --reload --reload-dir core --reload-dir config
|
||||
uvicorn config.asgi:application --host 0.0.0.0 --port 8000 --reload --reload-dir core --reload-dir config &
|
||||
|
||||
python3 core/bot/main.py &
|
||||
|
||||
wait
|
||||
|
||||
exit $?
|
||||
Reference in New Issue
Block a user