import typing from apps.authentication.api.v1.serializers.jwt import CustomizedTokenObtainPairSerializer from rest_framework_simplejwt.authentication import JWTAuthentication from rest_framework.decorators import action, permission_classes from apps.authentication import permissions as auth_permissions from apps.authentication.api.v1.serializers.serializer import ( CitySerializer, ProvinceSerializer, OrganizationTypeSerializer, OrganizationSerializer, UserSerializer, BankAccountSerializer ) from rest_framework_simplejwt.views import TokenObtainPairView from apps.authorization.api.v1 import api as authorize_view from rest_framework.viewsets import ModelViewSet from apps.authentication.models import ( User, City, Province, Organization, OrganizationType, BankAccountInformation ) from django.db import transaction from rest_framework.response import Response from common.tools import CustomOperations from rest_framework import status class CustomizedTokenObtainPairView(TokenObtainPairView): """ Generate Customize token """ serializer_class = CustomizedTokenObtainPairSerializer class UserViewSet(ModelViewSet): """ Crud operations for user model """ queryset = User.objects.all() serializer_class = UserSerializer permission_classes = [ auth_permissions.CreateUser, ] @transaction.atomic def create(self, request, *args, **kwargs): """ Customizing create user & bank account information with permission levels """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): user = serializer.save() if 'organization' in request.data.keys(): organization = CustomOperations().custom_create( # create organization for user request=request, view=OrganizationViewSet(), data_key='organization' ) else: organization = {} if 'user_relations' in request.data.keys(): user_relations = CustomOperations().custom_create( # create user relations user=user, request=request, view=authorize_view.UserRelationViewSet(), data_key='user_relations', additional_data={'organization': organization['id']} # noqa ) else: user_relations = {} if 'bank_account' in request.data.keys(): bank_account = CustomOperations().custom_create( # create user bank account info user=user, request=request, view=BankAccountViewSet(), data_key='bank_account' ) else: bank_account = {} serializer_data = serializer.data serializer_data.update({ 'organization': organization, 'user_relations': user_relations, # noqa 'bank_account': bank_account # noqa }) return Response(serializer_data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN) @transaction.atomic def update(self, request, pk=None, *args, **kwargs): """ Customizing update user & bank account info with permission levels """ serializer = self.serializer_class(data=request.data) if serializer.is_valid(): user = serializer.update(self.queryset.get(id=pk), validated_data=request.data) if 'organization' in request.data.keys(): # noqa organization = CustomOperations().custom_update( # update organization for user request=request, view=OrganizationViewSet(), data_key='organization', obj_id=request.data['organization']['id'] ) else: organization = {} if 'user_relations' in request.data.keys(): user_relations = CustomOperations().custom_update( # update user relations user=user, request=request, view=authorize_view.UserRelationViewSet(), data_key='user_relations', additional_data={'organization': request.data['organization']['id']}, # noqa obj_id=request.data['user_relations']['id'] ) else: user_relations = {} if 'bank_account' in request.data.keys(): bank_account = CustomOperations().custom_update( # update user bank account info user=user, request=request, view=BankAccountViewSet(), data_key='bank_account', obj_id=request.data['bank_account']['id'] ) else: bank_account = {} serializer_data = serializer.data serializer_data.update({ 'organization': organization, 'user_relations': user_relations, # noqa 'bank_account': bank_account # noqa }) return Response(serializer_data, status=status.HTTP_200_OK) else: return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN) class CityViewSet(ModelViewSet): """ Crud operations for city model """ # queryset = City.objects.all() serializer_class = CitySerializer class ProvinceViewSet(ModelViewSet): """ Crud operations for province model """ # queryset = Province.objects.all() serializer_class = ProvinceSerializer class OrganizationTypeViewSet(ModelViewSet): """ Crud operations for Organization Type model """ # queryset = OrganizationType.objects.all() serializer_class = OrganizationTypeSerializer class OrganizationViewSet(ModelViewSet): """ Crud operations for organization model """ # queryset = Organization.objects.all() serializer_class = OrganizationSerializer permission_classes = [auth_permissions.CreateOrganization] @transaction.atomic def create(self, request, *args, **kwargs): """ @create Organization by user """ serializer = self.serializer_class(data=request.data['organization']) if serializer.is_valid(): organization = serializer.save() if 'user_relations' in request.data.keys(): user_relations = CustomOperations().custom_create( # create user relations request=request, view=authorize_view.UserRelationViewSet(), data_key='user_relations', additional_data={'organization': organization.id} # noqa ) serializer_data = serializer.data serializer_data.update( {'user_relations': user_relations} ) return Response(serializer_data, status=status.HTTP_201_CREATED) else: return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_406_NOT_ACCEPTABLE) class BankAccountViewSet(ModelViewSet): """ Crud operations for bank account model """ # queryset = BankAccountInformation.objects.all() serializer_class = BankAccountSerializer