mirror of
https://github.com/Dadechin/Dashboard-XRoom.git
synced 2025-07-03 08:44:34 +00:00
Compare commits
2 Commits
17204180c8
...
b190fe0675
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b190fe0675 | ||
![]() |
24d745958e |
|
@ -1,7 +1,78 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from core.models.Meeting import Meeting
|
from core.models.Meeting import Meeting
|
||||||
|
from core.models.customer import Customer
|
||||||
|
from core.serializers.SpaceSerializer import SpaceSerializer
|
||||||
|
from core.serializers.CustomerSerializer import CustomerSerializer
|
||||||
|
from core.serializers.AssetBundleRoomSerializer import AssetBundleRoomSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MeetingSerializer(serializers.ModelSerializer):
|
class MeetingSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Meeting
|
model = Meeting
|
||||||
fields = ['id', 'name', 'description', 'date_time', 'creator_user', 'space', 'asset_bundle', 'use_space']
|
fields = ['id', 'name', 'description', 'date_time', 'creator_user', 'space', 'asset_bundle', 'use_space']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MeetingSerializerFull(serializers.ModelSerializer):
|
||||||
|
space_data = serializers.SerializerMethodField()
|
||||||
|
asset_bundle_data = serializers.SerializerMethodField()
|
||||||
|
invited_users = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Meeting
|
||||||
|
fields = [
|
||||||
|
'id', 'name', 'description', 'date_time', 'creator_user',
|
||||||
|
'use_space', 'space', 'asset_bundle',
|
||||||
|
'space_data', 'asset_bundle_data', 'invited_users'
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_space_data(self, obj):
|
||||||
|
if obj.use_space and obj.space:
|
||||||
|
return SpaceSerializer(obj.space).data # Replace with your actual Space serializer
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_asset_bundle_data(self, obj):
|
||||||
|
if not obj.use_space and obj.asset_bundle:
|
||||||
|
return AssetBundleRoomSerializer(obj.asset_bundle).data # Replace with your actual AssetBundle serializer
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_invited_users(self, obj):
|
||||||
|
invitations = obj.invitations.select_related('user')
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for invite in invitations:
|
||||||
|
user = invite.user
|
||||||
|
try:
|
||||||
|
customer = Customer.objects.get(user=user)
|
||||||
|
customer_data = CustomerSerializer(customer).data
|
||||||
|
except Customer.DoesNotExist:
|
||||||
|
customer_data = None
|
||||||
|
|
||||||
|
result.append({
|
||||||
|
"id": user.id,
|
||||||
|
"username": user.username,
|
||||||
|
"email": user.email,
|
||||||
|
"customer": customer_data
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
# def get_invited_users(self, obj):
|
||||||
|
# invitations = obj.invitations.select_related('user')
|
||||||
|
# return [
|
||||||
|
# {
|
||||||
|
# "id": invite.user.id,
|
||||||
|
# "username": invite.user.username,
|
||||||
|
# "email": invite.user.email,
|
||||||
|
# # add any custom customer fields you want
|
||||||
|
# }
|
||||||
|
# for invite in invitations
|
||||||
|
# ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ else:
|
||||||
'USER': 'root',
|
'USER': 'root',
|
||||||
'PASSWORD': '',
|
'PASSWORD': '',
|
||||||
'HOST': 'localhost',
|
'HOST': 'localhost',
|
||||||
'PORT': '3306',
|
'PORT': '3309',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,8 @@ urlpatterns = [
|
||||||
re_path('get_all_team_members', teamView.get_all_team_members),
|
re_path('get_all_team_members', teamView.get_all_team_members),
|
||||||
|
|
||||||
path('add_meeting', meetingView. addMeeting, name='add_meeting'),
|
path('add_meeting', meetingView. addMeeting, name='add_meeting'),
|
||||||
|
path('edit_meeting', meetingView. editMeeting, name='edit_meeting'),
|
||||||
|
path('get_user_meetings', meetingView. get_user_meetings, name='get_user_meetings'),
|
||||||
|
|
||||||
|
|
||||||
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
0
core/utils/__init__.py
Normal file
0
core/utils/__init__.py
Normal file
46
core/utils/sms.py
Normal file
46
core/utils/sms.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def send_sms(to_number, name, date_time, title):
|
||||||
|
# Try multiple datetime formats
|
||||||
|
dt = None
|
||||||
|
for fmt in ("%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%d %H:%M:%S%z"):
|
||||||
|
try:
|
||||||
|
dt = datetime.strptime(date_time, fmt)
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if dt is None:
|
||||||
|
return "Invalid datetime format"
|
||||||
|
|
||||||
|
# Format for SMS
|
||||||
|
date_str = dt.strftime("%Y/%m/%d")
|
||||||
|
time_str = dt.strftime("%H:%M")
|
||||||
|
|
||||||
|
# Message content
|
||||||
|
msg = f"""جناب {name}
|
||||||
|
شما در تاریخ {date_str}
|
||||||
|
ساعت {time_str}
|
||||||
|
به جلسه ی {title}
|
||||||
|
در متاورسی دعوت شده اید
|
||||||
|
my.xroomapp.com"""
|
||||||
|
|
||||||
|
# SMS service credentials
|
||||||
|
uname = "09399112092"
|
||||||
|
password = "Dadechin123!@##!"
|
||||||
|
from_number = "+983000505" # Replace with your SMS line number
|
||||||
|
|
||||||
|
# Request URL
|
||||||
|
url = (
|
||||||
|
f"https://sms.farazsms.com/class/sms/webservice/send_url.php"
|
||||||
|
f"?from={from_number}&to={to_number}&msg={msg}&uname={uname}&pass={password}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(url)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(url)
|
||||||
|
return response.text
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
|
@ -5,8 +5,10 @@ from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from drf_yasg.utils import swagger_auto_schema
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
from drf_yasg import openapi
|
from drf_yasg import openapi
|
||||||
from core.serializers.MeetingSerializer import MeetingSerializer
|
from core.serializers.MeetingSerializer import MeetingSerializer , MeetingSerializerFull
|
||||||
|
from core.utils.sms import send_sms # Assuming send_sms is in core/utils/sms.py
|
||||||
|
|
||||||
|
from core.models.Meeting import Meeting
|
||||||
|
|
||||||
# @swagger_auto_schema(
|
# @swagger_auto_schema(
|
||||||
# method='post',
|
# method='post',
|
||||||
|
@ -87,24 +89,38 @@ def addMeeting(request):
|
||||||
meeting = serializer.save()
|
meeting = serializer.save()
|
||||||
|
|
||||||
for user_id in user_ids:
|
for user_id in user_ids:
|
||||||
user = User.objects.get(id=user_id) # will raise exception if not found
|
try:
|
||||||
Invitation.objects.create(
|
user = User.objects.get(id=user_id)
|
||||||
user=user,
|
|
||||||
meeting=meeting,
|
# Create the invitation
|
||||||
is_admin=False,
|
Invitation.objects.create(
|
||||||
is_sms_sent=False
|
user=user,
|
||||||
)
|
meeting=meeting,
|
||||||
|
is_admin=False,
|
||||||
|
is_sms_sent=True # mark true if SMS sent below
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send SMS to user.username (which is a phone number)
|
||||||
|
sms_result = send_sms(
|
||||||
|
to_number=user.username,
|
||||||
|
name=user.get_full_name() or user.username,
|
||||||
|
date_time=str(meeting.date_time),
|
||||||
|
title=meeting.name
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"SMS sent to {user.username}: {sms_result}")
|
||||||
|
|
||||||
|
except User.DoesNotExist:
|
||||||
|
return Response(
|
||||||
|
{"error": f"User with id {user_id} does not exist."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
return Response({
|
return Response({
|
||||||
"message": "Meeting created successfully with invitations.",
|
"message": "Meeting created successfully with invitations and SMS sent.",
|
||||||
"meeting": serializer.data
|
"meeting": serializer.data
|
||||||
}, status=status.HTTP_201_CREATED)
|
}, status=status.HTTP_201_CREATED)
|
||||||
|
|
||||||
except User.DoesNotExist:
|
|
||||||
return Response(
|
|
||||||
{"error": f"User with id {user_id} does not exist."},
|
|
||||||
status=status.HTTP_400_BAD_REQUEST
|
|
||||||
)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response(
|
return Response(
|
||||||
{"error": str(e)},
|
{"error": str(e)},
|
||||||
|
@ -112,3 +128,125 @@ def addMeeting(request):
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# @swagger_auto_schema(
|
||||||
|
# method='get',
|
||||||
|
# operation_description="Get meetings created by or invited to the authenticated user.",
|
||||||
|
# responses={200: openapi.Response('Success', MeetingSerializer(many=True))}
|
||||||
|
# )
|
||||||
|
@api_view(['GET'])
|
||||||
|
@authentication_classes([SessionAuthentication, TokenAuthentication])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
def get_user_meetings(request):
|
||||||
|
try:
|
||||||
|
user = request.user
|
||||||
|
|
||||||
|
# Meetings the user created
|
||||||
|
created_meetings = Meeting.objects.filter(creator_user=user)
|
||||||
|
|
||||||
|
# Meetings the user was invited to
|
||||||
|
# invited_meetings = Meeting.objects.filter(invitation__user=user)
|
||||||
|
invited_meetings = Meeting.objects.filter(invitations__user=user)
|
||||||
|
|
||||||
|
|
||||||
|
# Combine both querysets and eliminate duplicates
|
||||||
|
all_meetings = (created_meetings | invited_meetings).distinct()
|
||||||
|
|
||||||
|
serializer = MeetingSerializerFull(all_meetings, many=True)
|
||||||
|
return Response({"meetings": serializer.data}, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@swagger_auto_schema(
|
||||||
|
method='post',
|
||||||
|
request_body=openapi.Schema(
|
||||||
|
type=openapi.TYPE_OBJECT,
|
||||||
|
required=['meeting_id', 'name', 'description', 'date_time', 'user_ids'],
|
||||||
|
properties={
|
||||||
|
'meeting_id': openapi.Schema(type=openapi.TYPE_INTEGER, default=1),
|
||||||
|
'name': openapi.Schema(type=openapi.TYPE_STRING, default='Updated Meeting'),
|
||||||
|
'description': openapi.Schema(type=openapi.TYPE_STRING, default='Updated description'),
|
||||||
|
'date_time': openapi.Schema(type=openapi.TYPE_STRING, format='date-time', default='2025-06-01T16:00:00Z'),
|
||||||
|
'space': openapi.Schema(type=openapi.TYPE_INTEGER, default=1),
|
||||||
|
'asset_bundle': openapi.Schema(type=openapi.TYPE_INTEGER, default=1),
|
||||||
|
'use_space': openapi.Schema(type=openapi.TYPE_BOOLEAN, default=False),
|
||||||
|
'user_ids': openapi.Schema(
|
||||||
|
type=openapi.TYPE_ARRAY,
|
||||||
|
items=openapi.Items(type=openapi.TYPE_INTEGER),
|
||||||
|
description='List of user IDs to invite'
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@api_view(['POST'])
|
||||||
|
@authentication_classes([SessionAuthentication, TokenAuthentication])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
def editMeeting(request):
|
||||||
|
data = request.data.copy()
|
||||||
|
user_ids = data.pop('user_ids', [])
|
||||||
|
meeting_id = data.get('meeting_id')
|
||||||
|
|
||||||
|
try:
|
||||||
|
meeting = Meeting.objects.get(id=meeting_id)
|
||||||
|
except Meeting.DoesNotExist:
|
||||||
|
return Response({"error": "Meeting not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
serializer = MeetingSerializer(meeting, data=data, partial=True)
|
||||||
|
|
||||||
|
if serializer.is_valid():
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
updated_meeting = serializer.save()
|
||||||
|
|
||||||
|
# Remove old invitations and add new ones
|
||||||
|
Invitation.objects.filter(meeting=meeting).delete()
|
||||||
|
|
||||||
|
for user_id in user_ids:
|
||||||
|
try:
|
||||||
|
user = User.objects.get(id=user_id)
|
||||||
|
Invitation.objects.create(
|
||||||
|
user=user,
|
||||||
|
meeting=meeting,
|
||||||
|
is_admin=False,
|
||||||
|
is_sms_sent=True
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send SMS notification
|
||||||
|
sms_result = send_sms(
|
||||||
|
to_number=user.username,
|
||||||
|
name=user.get_full_name() or user.username,
|
||||||
|
date_time=str(meeting.date_time),
|
||||||
|
title=meeting.name
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"SMS sent to {user.username}: {sms_result}")
|
||||||
|
|
||||||
|
except User.DoesNotExist:
|
||||||
|
return Response(
|
||||||
|
{"error": f"User with id {user_id} does not exist."},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
|
return Response({
|
||||||
|
"message": "Meeting updated successfully with new invitations and SMS sent.",
|
||||||
|
"meeting": serializer.data
|
||||||
|
}, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user