add notification and send notification
This commit is contained in:
@@ -30,6 +30,7 @@ APPS = [
|
|||||||
'core.apps.orders',
|
'core.apps.orders',
|
||||||
'core.apps.finance',
|
'core.apps.finance',
|
||||||
'core.apps.counterparty',
|
'core.apps.counterparty',
|
||||||
|
'core.apps.notifications',
|
||||||
]
|
]
|
||||||
|
|
||||||
PACKAGES = [
|
PACKAGES = [
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ urlpatterns = [
|
|||||||
path('orders/', include('core.apps.orders.urls')),
|
path('orders/', include('core.apps.orders.urls')),
|
||||||
path('finance/', include('core.apps.finance.urls')),
|
path('finance/', include('core.apps.finance.urls')),
|
||||||
path('counterparties/', include('core.apps.counterparty.urls')),
|
path('counterparties/', include('core.apps.counterparty.urls')),
|
||||||
|
path('notifications/', include('core.apps.notifications.urls')),
|
||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
|
|
||||||
|
|||||||
0
core/apps/notifications/__init__.py
Normal file
0
core/apps/notifications/__init__.py
Normal file
6
core/apps/notifications/apps.py
Normal file
6
core/apps/notifications/apps.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationsConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'core.apps.notifications'
|
||||||
31
core/apps/notifications/migrations/0001_initial.py
Normal file
31
core/apps/notifications/migrations/0001_initial.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 5.2.4 on 2025-10-28 15:45
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Notification',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('token', models.CharField(max_length=255, unique=True)),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
0
core/apps/notifications/migrations/__init__.py
Normal file
0
core/apps/notifications/migrations/__init__.py
Normal file
1
core/apps/notifications/models/__init__.py
Normal file
1
core/apps/notifications/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from .notification import *
|
||||||
9
core/apps/notifications/models/notification.py
Normal file
9
core/apps/notifications/models/notification.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from core.apps.shared.models import BaseModel
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
|
||||||
|
class Notification(BaseModel):
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notifications')
|
||||||
|
token = models.CharField(max_length=255, unique=True)
|
||||||
|
|
||||||
11
core/apps/notifications/serializers/notification.py
Normal file
11
core/apps/notifications/serializers/notification.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from core.apps.notifications.models import Notification
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Notification
|
||||||
|
fields = [
|
||||||
|
'token'
|
||||||
|
]
|
||||||
7
core/apps/notifications/urls.py
Normal file
7
core/apps/notifications/urls.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from core.apps.notifications.views import notification
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('device/register/', notification.RegisterExpoPushToken.as_view()),
|
||||||
|
]
|
||||||
8
core/apps/notifications/utils/notify_user.py
Normal file
8
core/apps/notifications/utils/notify_user.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from core.apps.notifications.models import Notification
|
||||||
|
from core.apps.notifications.utils.send_notification import send_notification
|
||||||
|
|
||||||
|
|
||||||
|
def notify_user(user, title, body):
|
||||||
|
tokens = Notification.objects.filter(user=user)
|
||||||
|
for token in tokens:
|
||||||
|
send_notification(token.token, title, body)
|
||||||
16
core/apps/notifications/utils/send_notification.py
Normal file
16
core/apps/notifications/utils/send_notification.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import requests
|
||||||
|
|
||||||
|
def send_notification(token, title, body, data=None):
|
||||||
|
message = {
|
||||||
|
"to": token,
|
||||||
|
"sound": "default",
|
||||||
|
"title": title,
|
||||||
|
"body": body,
|
||||||
|
"data": data or {},
|
||||||
|
}
|
||||||
|
response = requests.post(
|
||||||
|
"https://exp.host/--/api/v2/push/send",
|
||||||
|
json=message,
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
return response.json()
|
||||||
20
core/apps/notifications/views/notification.py
Normal file
20
core/apps/notifications/views/notification.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from rest_framework import generics, status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from core.apps.notifications.serializers import notification as serializers
|
||||||
|
from core.apps.notifications.models import Notification
|
||||||
|
|
||||||
|
|
||||||
|
class RegisterExpoPushToken(generics.GenericAPIView):
|
||||||
|
serializer_class = serializers.NotificationSerializer
|
||||||
|
queryset = Notification.objects.all()
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
serializer = self.serializer_class(data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
Notification.objects.update_or_create(
|
||||||
|
user=request.user,
|
||||||
|
token=serializer.validated_data['token']
|
||||||
|
)
|
||||||
|
return Response({"message": "Token saqlandi"}, status=status.HTTP_201_CREATED)
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
@@ -16,6 +16,8 @@ from core.apps.projects.models import Project, ProjectFolder
|
|||||||
from core.apps.projects.serializers.project import ProjectListSerializer, ProjectFolderListSerializer
|
from core.apps.projects.serializers.project import ProjectListSerializer, ProjectFolderListSerializer
|
||||||
# counterparty
|
# counterparty
|
||||||
from core.apps.counterparty.models import Counterparty
|
from core.apps.counterparty.models import Counterparty
|
||||||
|
# notifications
|
||||||
|
from core.apps.notifications.utils.notify_user import notify_user
|
||||||
|
|
||||||
|
|
||||||
class OrderCreateSerializer(serializers.Serializer):
|
class OrderCreateSerializer(serializers.Serializer):
|
||||||
@@ -71,7 +73,7 @@ class MultipleOrderCreateSerializer(serializers.Serializer):
|
|||||||
orders = []
|
orders = []
|
||||||
|
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
orders.append(Order(
|
order = Order(
|
||||||
product=resource['product'],
|
product=resource['product'],
|
||||||
unity=resource['unity'],
|
unity=resource['unity'],
|
||||||
wherehouse=resource['wherehouse'],
|
wherehouse=resource['wherehouse'],
|
||||||
@@ -80,8 +82,16 @@ class MultipleOrderCreateSerializer(serializers.Serializer):
|
|||||||
quantity=resource['quantity'],
|
quantity=resource['quantity'],
|
||||||
date=common_date,
|
date=common_date,
|
||||||
employee=self.context.get('user'),
|
employee=self.context.get('user'),
|
||||||
))
|
)
|
||||||
|
orders.append(order)
|
||||||
|
body = f"""
|
||||||
|
{user.full_name} {order.project_folder.name} uchun {order.wherehouse.name} ombor ga {order.quantity} {order.unity.value} {order.product.name} ga buyurtma berdi. Buyurtma
|
||||||
|
yetkazish sanasi {common_date}
|
||||||
|
"""
|
||||||
|
notify_user(user=self.context.get("user"), title="Ta'minot",body=body)
|
||||||
|
|
||||||
created_orders = Order.objects.bulk_create(orders)
|
created_orders = Order.objects.bulk_create(orders)
|
||||||
|
user = self.context.get('user')
|
||||||
return created_orders
|
return created_orders
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user