Tag Assignment - organization OTP
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import typing
|
||||
|
||||
from rest_framework.permissions import AllowAny
|
||||
from apps.authentication.api.v1.serializers.jwt import CustomizedTokenObtainPairSerializer
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
from rest_framework.decorators import action, permission_classes
|
||||
@@ -26,7 +26,10 @@ from apps.authentication.models import (
|
||||
from django.db import transaction
|
||||
from rest_framework.response import Response
|
||||
from common.tools import CustomOperations
|
||||
from django.core.cache import cache
|
||||
from rest_framework import status
|
||||
from common.sms import send_sms
|
||||
import random
|
||||
|
||||
|
||||
class CustomizedTokenObtainPairView(TokenObtainPairView):
|
||||
@@ -138,6 +141,20 @@ class UserViewSet(ModelViewSet):
|
||||
else:
|
||||
return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@action(
|
||||
methods=['get'],
|
||||
detail=False,
|
||||
url_name='profile',
|
||||
url_path='profile',
|
||||
name='profile',
|
||||
permission_classes=[AllowAny]
|
||||
)
|
||||
def profile(self, request):
|
||||
serializer = authorize_view.UserRelationSerializer(
|
||||
authorize_view.UserRelations.objects.get(user=request.user)
|
||||
)
|
||||
return Response(serializer.data, status.HTTP_200_OK)
|
||||
|
||||
|
||||
class CityViewSet(ModelViewSet):
|
||||
""" Crud operations for city model """ #
|
||||
@@ -195,3 +212,76 @@ class BankAccountViewSet(ModelViewSet):
|
||||
""" Crud operations for bank account model """ #
|
||||
queryset = BankAccountInformation.objects.all()
|
||||
serializer_class = BankAccountSerializer
|
||||
|
||||
|
||||
class GeneralOTPViewSet(ModelViewSet):
|
||||
""" general OTP user authorization """
|
||||
|
||||
user_relations_queryset = authorize_view.UserRelations.objects.all()
|
||||
organization_queryset = Organization.objects.all()
|
||||
user_queryset = User.objects.all()
|
||||
user_serializer = UserSerializer
|
||||
organization_serializer = OrganizationSerializer
|
||||
user_relations_serializer = authorize_view.UserRelationSerializer
|
||||
|
||||
@classmethod
|
||||
def get_user_mobile(cls, data: dict) -> typing.Any:
|
||||
""" find user mobile in multiple modes like from organization """
|
||||
|
||||
if data['get_mobile_type'] == 'organization':
|
||||
# get user mobile by his/her organization
|
||||
user_mobile = cls.user_relations_queryset.filter(
|
||||
organization_id=int(data['object_id']),
|
||||
role__role_name='Management').first().user.mobile
|
||||
return user_mobile
|
||||
|
||||
if data['get_mobile_type'] == 'general':
|
||||
return data['mobile']
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=False,
|
||||
url_path='send_otp',
|
||||
url_name='send_otp',
|
||||
name='send_otp'
|
||||
)
|
||||
@transaction.atomic
|
||||
def send_otp(self, request):
|
||||
"""
|
||||
This module is for sending otp in whole project and different parts
|
||||
like send otp code to user by organization or by general user mobile
|
||||
"""
|
||||
|
||||
mobile = self.get_user_mobile(
|
||||
data=request.data
|
||||
)
|
||||
|
||||
# generate random integer and message for otp code
|
||||
random_number = random.randint(10000, 99999)
|
||||
message = f'کد احراز شما : {random_number}' # noqa
|
||||
|
||||
# caching code
|
||||
if 'timeout' in request.data.keys():
|
||||
cache.set(f"{random_number}", str(random_number), timeout=60 * int(request.data['timeout']))
|
||||
else:
|
||||
cache.set(f"{random_number}", str(random_number), timeout=60 * 3)
|
||||
|
||||
sms_response = send_sms(mobile=mobile, message=message)
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=False,
|
||||
url_name='check_otp',
|
||||
url_path='check_otp',
|
||||
name='check_otp'
|
||||
)
|
||||
def check_otp(self, request):
|
||||
""" Check sent otp code to user """
|
||||
|
||||
entered_code = request.data['code']
|
||||
cached_code = cache.get(entered_code)
|
||||
|
||||
if entered_code == cached_code:
|
||||
return Response(status=status.HTTP_200_OK)
|
||||
return Response(status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@@ -12,7 +12,8 @@ from .api import (
|
||||
CityViewSet,
|
||||
ProvinceViewSet,
|
||||
OrganizationViewSet,
|
||||
OrganizationTypeViewSet
|
||||
OrganizationTypeViewSet,
|
||||
GeneralOTPViewSet
|
||||
)
|
||||
|
||||
router = DefaultRouter()
|
||||
@@ -21,6 +22,7 @@ router.register(r'city', CityViewSet, basename='city')
|
||||
router.register(r'province', ProvinceViewSet, basename='province')
|
||||
router.register(r'organization', OrganizationViewSet, basename='organization')
|
||||
router.register(r'organization-type', OrganizationTypeViewSet, basename='organization_type')
|
||||
router.register(r'otp', GeneralOTPViewSet, basename='otp')
|
||||
|
||||
urlpatterns = [
|
||||
path('login/', CustomizedTokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
|
||||
@@ -6,6 +6,7 @@ from apps.core.models import BaseModel
|
||||
from crum import get_current_user
|
||||
from django.db import models
|
||||
from jdatetime import datetime
|
||||
import random
|
||||
|
||||
|
||||
class Tag(BaseModel):
|
||||
@@ -85,6 +86,7 @@ class TagAssignment(BaseModel):
|
||||
)[3] + str(
|
||||
datetime.now().month
|
||||
)
|
||||
self.serial_random_part = random.randint(1000, 9999)
|
||||
if not self.serial:
|
||||
self.serial = f"" \
|
||||
f"{self.serial_sender_part}" \
|
||||
|
||||
@@ -12,6 +12,7 @@ from django.db import transaction
|
||||
from rest_framework.exceptions import APIException
|
||||
from apps.tag import permissions as tag_permissions
|
||||
from apps.authorization import models as authorize_models
|
||||
from apps.authentication.api.v1.api import GeneralOTPViewSet
|
||||
from apps.tag.tools import tag_code_serial_scanning
|
||||
from apps.tag import exceptions as tag_exceptions
|
||||
from common.helpers import detect_file_extension
|
||||
@@ -110,6 +111,7 @@ class TagViewSet(viewsets.ModelViewSet):
|
||||
class TagAssignmentViewSet(viewsets.ModelViewSet):
|
||||
""" assignment of tags """
|
||||
queryset = tag_models.TagAssignment.objects.all()
|
||||
user_relations_queryset = authorize_models.UserRelations.objects.all()
|
||||
serializer_class = TagAssignmentSerializer
|
||||
|
||||
@transaction.atomic
|
||||
@@ -120,6 +122,12 @@ class TagAssignmentViewSet(viewsets.ModelViewSet):
|
||||
if serializer.is_valid(raise_exception=True):
|
||||
tag_assignment = serializer.save()
|
||||
|
||||
# get assigner organization code
|
||||
assigner_organization_code = self.user_relations_queryset.get(
|
||||
user=request.user).organization.type.code # noqa
|
||||
tag_assignment.serial_sender_part = assigner_organization_code # noqa
|
||||
tag_assignment.save()
|
||||
|
||||
# get tags by species number like: 2 tags of species code 4
|
||||
tags_to_allocate = request.data['allocated_tags']
|
||||
for tag in tags_to_allocate:
|
||||
@@ -140,7 +148,7 @@ class TagAssignmentViewSet(viewsets.ModelViewSet):
|
||||
status='W',
|
||||
species_code=tag['species_code']
|
||||
).save() # noqa
|
||||
tag_to_allocate.status = 'W' # change tag status from free to waiting
|
||||
tag_to_allocate.status = ' ' # change tag status from free to waiting
|
||||
tag_to_allocate.save()
|
||||
|
||||
return Response(serializer.data, status.HTTP_201_CREATED)
|
||||
@@ -207,6 +215,29 @@ class TagAssignmentViewSet(viewsets.ModelViewSet):
|
||||
allocated_tag.delete()
|
||||
return Response(status.HTTP_200_OK)
|
||||
|
||||
@action(
|
||||
methods=['post'],
|
||||
detail=False,
|
||||
url_path='otp_verification',
|
||||
url_name='otp_verification',
|
||||
name='otp_verification'
|
||||
)
|
||||
def otp_verification(self, request):
|
||||
""" OTP verification for organization """
|
||||
|
||||
if request.data['type'] == 'send':
|
||||
otp_response = GeneralOTPViewSet().send_otp(request)
|
||||
if otp_response.status_code == 200:
|
||||
return Response(otp_response.status_code, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response(otp_response.status_code, status=status.HTTP_403_FORBIDDEN)
|
||||
if request.data['type'] == 'check':
|
||||
check_response = GeneralOTPViewSet().check_otp(request)
|
||||
if check_response.status_code == 200:
|
||||
return Response(check_response.status_code, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response(check_response.status_code, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@action(
|
||||
methods=['put'],
|
||||
detail=True,
|
||||
|
||||
21
common/sms.py
Normal file
21
common/sms.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import typing
|
||||
import requests
|
||||
|
||||
USERNAME_SMS = 'hamedan' # noqa # Sahand Sms username
|
||||
PASSWORD_SMS = 'hamedan12345' # noqa # Sahand sms password
|
||||
|
||||
|
||||
def send_sms(mobile: str = None, message: str = None) -> typing.Any:
|
||||
""" send sms to a number with custom message """
|
||||
|
||||
url = f"http://webservice.sahandsms.com/newsmswebservice.asmx/SendPostUrl?" \
|
||||
f"username={USERNAME_SMS}&password={PASSWORD_SMS}" \
|
||||
f"&from=30002501&to={mobile}&message={message}"
|
||||
|
||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
response = requests.request('GET', url, headers=headers)
|
||||
print(response)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
send_sms(mobile="09389657326", message="12345")
|
||||
Reference in New Issue
Block a user