From e70150f726c869cec8d8519c3bdcd5dd1d8e50cc Mon Sep 17 00:00:00 2001 From: MJ Akbari Date: Sat, 21 Sep 2024 15:56:38 +0330 Subject: [PATCH 1/3] payment --- GD/messages.py | 70 ++++++++++----------- GD/settings/base.py | 3 +- core/admin.py | 18 +++--- core/models.py | 54 +++++++++++++++- core/views.py | 39 +++++++----- game/serializers.py | 4 +- requirements.txt | 1 + user/admin.py | 31 ++++++++-- user/models.py | 12 ++++ user/serializers.py | 19 +++--- user/views.py | 146 ++++++++++++++++++++++++++++++++++++-------- 11 files changed, 288 insertions(+), 109 deletions(-) diff --git a/GD/messages.py b/GD/messages.py index 8086192..024ae9b 100644 --- a/GD/messages.py +++ b/GD/messages.py @@ -1,47 +1,43 @@ - # talk and work shop -CAPACITY_IS_FULL= 'ظرفیت پر است' -USER_HAS_ALREADY_ENROLLED='شما قبلا ثبت نام کرده اید' -SUCCESSFULLY_ADDED='باموفقیت اضافه شد' -NO_ANY_SERVICES='هیچ سرویسی وجود ندارد' -INACTIVE='غیرفعال است' - +CAPACITY_IS_FULL = 'ظرفیت پر است' +USER_HAS_ALREADY_ENROLLED = 'شما قبلا ثبت نام کرده اید' +SUCCESSFULLY_ADDED = 'باموفقیت اضافه شد' +NO_ANY_SERVICES = 'هیچ سرویسی وجود ندارد' +INACTIVE = 'غیرفعال است' # user and activation -USER_DELETED_SUCCESSFULLY='یوزر باموقیت حذف شد' -LOG_OUT_FAILD='خروج ناموفق' -DUPLICATE_USER_ERROR='یوزری با این مشخصات قبلا ثبت شده است' -USER_LOGED_OUT_SUCCESSFULLY='با موفقیت خارج شدید' -USER_ACTIVED='یوزر فعال شد' -USER_NOT_FOUND='یوزری پیدا نشد' -USER_CREATED_SUCCESSFULLY='یوزر با موفقیت ثبت شد' +USER_DELETED_SUCCESSFULLY = 'یوزر باموقیت حذف شد' +LOG_OUT_FAILD = 'خروج ناموفق' +DUPLICATE_USER_ERROR = 'یوزری با این مشخصات قبلا ثبت شده است' +USER_LOGED_OUT_SUCCESSFULLY = 'با موفقیت خارج شدید' +USER_ACTIVED = 'یوزر فعال شد' +USER_NOT_FOUND = 'یوزری پیدا نشد' +USER_CREATED_SUCCESSFULLY = 'یوزر با موفقیت ثبت شد' # payment and shopping_cart -WORKSHOP_CAPACITY_IS_FULL='\nظرفیت این کارگاه پر است \nلطفا این کارگاه را از سبد خود پاک کنید' -SHOPPING_CART_EMPTY= 'سبد خرید شما خالی است' -COUPON_FINISHED='ظرفیت این کد تخفیف تمام شده است' -COUPON_DOSE_NOT_EXIST='این کد تخفیف وجود ندارد و غیر معتبر هست' -CREATING_PAYMENT_UNSUCCESS='متاسفانه پرداخت ساخته نشد \n لطفا مجدد تلاش کنید' -INACTIVE_WORKSHOP_EXISTS= 'کارگاهی غیرفعال در سبد خرید شما وجود دارد!\n آن را حذف کنید و دوباره امتحان کنید.' +WORKSHOP_CAPACITY_IS_FULL = '\nظرفیت این کارگاه پر است \nلطفا این کارگاه را از سبد خود پاک کنید' +SHOPPING_CART_EMPTY = 'سبد خرید شما خالی است' +COUPON_FINISHED = 'ظرفیت این کد تخفیف تمام شده است' +COUPON_DOSE_NOT_EXIST = 'این کد تخفیف وجود ندارد و غیر معتبر هست' +CREATING_PAYMENT_UNSUCCESS = 'متاسفانه پرداخت ساخته نشد \n لطفا مجدد تلاش کنید' +INACTIVE_WORKSHOP_EXISTS = 'کارگاهی غیرفعال در سبد خرید شما وجود دارد!\n آن را حذف کنید و دوباره امتحان کنید.' # competition -ADDED_TO_COMPETITION='باموفقیت به مسابقه اضافه شدید' -ALREADY_REGISTERED_IN_THE_COMPETITION='شما قبلا در مسابقه ثبت نام کرده اید' - +ADDED_TO_COMPETITION = 'باموفقیت به مسابقه اضافه شدید' +ALREADY_REGISTERED_IN_THE_COMPETITION = 'شما قبلا در مسابقه ثبت نام کرده اید' # team -REQUESTED_USER_IS_NOT_REGISTERED_OR_ALREADY_HAS_A_TEAM='کاربر درخواستی شما یا تیم دارد یا ثبت نام نکرده است' -YOU_ALREADY_HAVE_A_TEAM='شما در حال حاضر تیم دارید' -COUNT_OF_USER_MEMBERS_MUST_BE_BETWEEN='تعداد اعضای گروه باید بین ۲ تا ۵ باشد' -USER_X_HAS_TEAM=' کاربر {user} تیم دارد' -USER_ALREADY_HAS_A_TEAM='کاربر تیم دارد' -TEAM_ACTIVED='تیم فعال شد' -TEAM_NOT_FOUND='تیم پیدا نشد' -TEAM_IS_FULL='تیم پر است' -TEAM_IS_REJECTED='تیم رد شده است' +REQUESTED_USER_IS_NOT_REGISTERED_OR_ALREADY_HAS_A_TEAM = 'کاربر درخواستی شما یا تیم دارد یا ثبت نام نکرده است' +YOU_ALREADY_HAVE_A_TEAM = 'شما در حال حاضر تیم دارید' +COUNT_OF_USER_MEMBERS_MUST_BE_BETWEEN = 'تعداد اعضای گروه باید بین ۲ تا ۵ باشد' +USER_X_HAS_TEAM = ' کاربر {user} تیم دارد' +USER_ALREADY_HAS_A_TEAM = 'کاربر تیم دارد' +TEAM_ACTIVED = 'تیم فعال شد' +TEAM_NOT_FOUND = 'تیم پیدا نشد' +TEAM_IS_FULL = 'تیم پر است' +TEAM_IS_REJECTED = 'تیم رد شده است' +TEAM_NOT_ACCEPTED = 'تیم فعال نیست' # general -CORRECT_THE_ERRORS='لطفا مشخصات را کامل و به درستی وارد کنید' -EMPTY='هیچ رکوردی وجود ندارد' -SOMETHING_IS_WRONG='مشکلی وجود دارد' - - +CORRECT_THE_ERRORS = 'لطفا مشخصات را کامل و به درستی وارد کنید' +EMPTY = 'هیچ رکوردی وجود ندارد' +SOMETHING_IS_WRONG = 'مشکلی وجود دارد' diff --git a/GD/settings/base.py b/GD/settings/base.py index 052664d..0e5e0e9 100644 --- a/GD/settings/base.py +++ b/GD/settings/base.py @@ -41,7 +41,8 @@ 'rest_framework_simplejwt.token_blacklist', 'corsheaders', 'tinymce', - 'drf_yasg' + 'drf_yasg', + 'solo', # 'anymail' ] diff --git a/core/admin.py b/core/admin.py index 3a9eb80..6cac008 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,8 +1,7 @@ -from datetime import timezone - import jdatetime -from dill import objects from django.contrib import admin +from solo.admin import SingletonModelAdmin + from core.models import ( Assistant, Workshop, @@ -10,16 +9,10 @@ EventService, Talk, Payment, - Coupon, - PAYMENT_STATES + Coupon, SingletonCompetition, ) -from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from tasks.tasks import reminder_email_task - -import tempfile -import zipfile -from django.http import HttpResponse, JsonResponse -import csv +from django.http import JsonResponse class PresenterTalkInline(admin.TabularInline): @@ -250,3 +243,6 @@ class CouponAdmin(admin.ModelAdmin): 'name', 'count', 'percentage' ) list_display = ['name', 'count', 'percentage'] + + +admin.site.register(SingletonCompetition, SingletonModelAdmin) diff --git a/core/models.py b/core/models.py index 1677d87..2e1b83f 100644 --- a/core/models.py +++ b/core/models.py @@ -1,8 +1,10 @@ from django.db import models from rest_framework.exceptions import ValidationError from datetime import datetime + +from solo.models import SingletonModel + from GD.settings.base import AUTH_USER_MODEL, PAYWALL -from .validators import validate_file_extension from tinymce.models import HTMLField IDPAY_STATUS = [ @@ -43,6 +45,7 @@ SERVICE_TYPE = [ ('WS', 'WORKSHOP'), ('TK', 'TALK'), + ('CP', 'COMPETITION') ] LEVEL = [ @@ -160,6 +163,44 @@ def __str__(self): return self.title +class SingletonCompetition(SingletonModel): + title = models.CharField(max_length=100, blank=False, default="Game Craft Competition") + start = models.DateTimeField(blank=False, default=datetime(year=2024, month=1, day=1)) + end = models.DateTimeField(blank=False, default=datetime(year=2024, month=1, day=1)) + content = HTMLField(blank=True) + capacity = models.IntegerField(blank=False, default=60) + is_online = models.BooleanField(blank=False, default=False) + presentation_link = models.URLField(blank=True) + cost = models.FloatField(blank=False, default=0) + files = models.URLField(default=None, blank=True, null=True) + is_registration_active = models.BooleanField(blank=False, default=False) + + def clean(self): + if self.cost < 0: + raise ValidationError("cost cann't be a negative number.") + if self.start > self.end: + raise ValidationError("end of the service can not be before beginning") + + def get_total_services(self): + return self.services.count() + + def get_is_registration_active(self): + return self.is_registration_active + + def get_services(self): + return self.services.all() + + def get_remain_capacity(self): + registered_user = self.services.filter(payment_state='CM').count() + return self.capacity - int(registered_user) + + def registered(self): + return int(self.services.filter(payment_state='CM').count()) + + def __str__(self): + return self.title + + class Coupon(models.Model): name = models.CharField(max_length=50, primary_key=True, help_text="don't use / in the name!!!") count = models.PositiveIntegerField(null=False, blank=False) @@ -218,16 +259,23 @@ class EventService(models.Model): Talk, blank=True, on_delete=models.CASCADE, related_name='services', null=True) workshop = models.ForeignKey( Workshop, blank=True, on_delete=models.CASCADE, related_name='services', null=True) + competition = models.ForeignKey( + SingletonCompetition, blank=True, on_delete=models.CASCADE, related_name='services', null=True) + user = models.ForeignKey( AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='services', null=True) def clean(self): if self.service_type == 'WS': - if self.workshop == None or self.talk != None: + if self.workshop == None or self.talk != None or self.competition != None: raise ValidationError( 'service type must match with selected service!!!') if self.service_type == 'TK': - if self.talk == None or self.workshop != None: + if self.talk == None or self.workshop != None or self.competition != None: + raise ValidationError( + 'service type must match with selected service!!!') + if self.service_type == 'CP': + if self.competition == None or self.workshop != None or self.talk != None: raise ValidationError( 'service type must match with selected service!!!') diff --git a/core/views.py b/core/views.py index 37c8757..ab62c9c 100644 --- a/core/views.py +++ b/core/views.py @@ -146,17 +146,17 @@ def payment(self, request): result['code']) payment.coupon = coupon payment.save() - if PAYWALL != 'idpay': - _code = result['code'] - _status = result['status'] - result = { - "link": PayPingPeymentLinkGenerator(_code), - "status": _status - } - return self.set_response( - message=None, data=result, status_code=status.HTTP_200_OK - ) - # return redirect('http://gamecraft.ce.aut.ac.ir') + + if PAYWALL != 'idpay': + _code = result['code'] + _status = result['status'] + result = { + "link": PayPingPeymentLinkGenerator(_code), + "status": _status + } + return self.set_response( + message=None, data=result, status_code=status.HTTP_200_OK + ) else: payment.delete() if coupon: @@ -187,12 +187,15 @@ def verify(self, request): if any(result_status == status_code for status_code in (IDPAY_STATUS_100, IDPAY_STATUS_101, IDPAY_STATUS_200)): - services = EventService.objects.select_related( - 'workshop').filter(payment=payment) + services = EventService.objects.filter(payment=payment) for service in services: service.payment_state = 'CM' - service.workshop.save() + if service.workshop: + service.workshop.save() + elif service.competition: + service.competition.save() service.save() + payment.status = result_status payment.original_data = json.dumps(result) payment.verify_trackID = result['track_id'] @@ -242,11 +245,15 @@ def verify(self, request): _payment.card_number = result['cardNumber'] _payment.hashed_card_number = result["cardHashPan"] _payment.payment_trackID = _payment.payment_id - services = EventService.objects.select_related('workshop').filter(payment=_payment) + services = EventService.objects.filter(payment=_payment) for service in services: service.payment_state = 'CM' - service.workshop.save() + if service.workshop: + service.workshop.save() + elif service.competition: + service.competition.save() service.save() + _payment.status = result['status'] _payment.original_data = json.dumps(result) _payment.verify_trackID = _payment.payment_id diff --git a/game/serializers.py b/game/serializers.py index 37cd8aa..d48bdaf 100644 --- a/game/serializers.py +++ b/game/serializers.py @@ -4,7 +4,7 @@ from user.models import SiteUser, Team from user.serializers import UserSerializerMinimal from django.core.validators import MaxValueValidator, MinValueValidator -from user.serializers import TeamSerialzer +from user.serializers import TeamSerializer from rest_framework.exceptions import ValidationError from decouple import config @@ -119,7 +119,7 @@ def get_likes(self, object): def to_representation(self, obj): - self.fields["team"] = TeamSerialzer() + self.fields["team"] = TeamSerializer() return super(GameSerializer, self).to_representation(obj) diff --git a/requirements.txt b/requirements.txt index 1ee3b03..276dab6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,6 +18,7 @@ django-debug-toolbar==4.4.6 django-excel-response==2.0.5 django-extensions==3.2.3 django-filter==24.2 +django-solo==2.3.0 django-tinymce==4.1.0 djangorestframework==3.15.2 djangorestframework-simplejwt==5.3.1 diff --git a/user/admin.py b/user/admin.py index 3bf30a5..8b3c09b 100644 --- a/user/admin.py +++ b/user/admin.py @@ -18,7 +18,7 @@ def export_selected_users(self, request, queryset): def export_selected_services(self, request, queryset): data = [] - headers = ['Username / Email', 'Phone Number', 'Name', 'Talk / workshop'] + headers = ['Email', 'Phone Number', 'Name', 'Talk / workshop'] for user in queryset: for service in user.services.all(): @@ -107,6 +107,22 @@ class UserTeamInline(admin.TabularInline): @admin.register(Team) class TeamAdmin(admin.ModelAdmin): + def export_enrolled_teams(self, request, queryset): + data = [] + headers = ['Email', 'Phone Number', 'Name', 'Team'] + + for team in queryset.all(): + if team.get_payment_state() == "COMPLETED": + for user in team.members.all(): + data.append([user.email, user.phone_number, user.first_name, team]) + + data.sort(key=lambda x: x[3]) + data.insert(0, headers) + return ExcelResponse(data=data, worksheet_name="Services", output_filename="services") + + def payment_state(self, obj): + return obj.get_payment_state() + fieldsets = ( (None, { "fields": ( @@ -116,17 +132,20 @@ class TeamAdmin(admin.ModelAdmin): ( 'register state', { 'fields': ( - 'state', 'team_activation' + 'state', 'team_activation', 'payment_state' ) } ) ) - list_display = ['id', 'name', 'state', 'member_count'] + + actions = ['export_enrolled_teams'] + export_enrolled_teams.short_description = 'Export enrolled teams' actions_on_top = True + + readonly_fields = ['payment_state', ] + list_display = ['id', 'name', 'state', 'member_count'] list_filter = ['state'] - inlines = [ - UserTeamInline, - ] + inlines = [UserTeamInline, ] admin.site.register(SiteUser, UserAdminConfig) diff --git a/user/models.py b/user/models.py index 453b583..3e518e6 100644 --- a/user/models.py +++ b/user/models.py @@ -13,6 +13,8 @@ import logging +from core.models import SingletonCompetition, EventService + logger = logging.getLogger(__name__) DEFAULT_AVATARS = [ @@ -51,6 +53,16 @@ class Team(models.Model): verbose_name='team_profile', null=True, blank=True) team_activation = models.CharField(max_length=40, null=True, blank=True, unique=True) + def get_payment_state(self): + for member in self.members.all(): + args = {'user': member, 'competition': SingletonCompetition.get_solo(), + 'service_type': 'CP', 'payment_state': 'CM'} + query = EventService.objects.filter(**args) + if query.exists(): + return "COMPLETED" + else: + return "PENDING" + def member_count(self): return self.members.count() diff --git a/user/serializers.py b/user/serializers.py index bc7bba1..115c47e 100644 --- a/user/serializers.py +++ b/user/serializers.py @@ -3,8 +3,8 @@ from rest_framework import serializers from django.contrib.auth import get_user_model -from rest_framework_simplejwt.serializers import TokenObtainPairSerializer +from core.models import SingletonCompetition, EventService from .models import ( PhoneValidator, SiteUser, @@ -37,7 +37,7 @@ def create(self, validated_data): return instance -class UserTeamSerialzier(serializers.ModelSerializer): +class UserTeamSerializer(serializers.ModelSerializer): def get_profile(self, member): try: @@ -54,20 +54,21 @@ class Meta: extra_kwargs = {'pk': {'read_only': True}} -class TeamSerialzer(serializers.ModelSerializer): +class TeamSerializer(serializers.ModelSerializer): def get_state(self, obj): return obj.get_state_display() + def get_payment_state(self, obj): + obj.get_payment_state() + state = serializers.SerializerMethodField() - emails = serializers.ListField( - write_only=True, child=serializers.EmailField()) - members = UserTeamSerialzier(many=True) + payment_state = serializers.SerializerMethodField() + emails = serializers.ListField(write_only=True, child=serializers.EmailField()) + members = UserTeamSerializer(many=True) class Meta: model = Team - fields = [ - 'members', 'state', 'emails', 'name', 'pk' - ] + fields = ['members', 'state', 'emails', 'name', 'pk', 'payment_state'] extra_kwargs = {'pk': {'read_only': True}} def create(self, validated_data): diff --git a/user/views.py b/user/views.py index 3865748..238c473 100644 --- a/user/views.py +++ b/user/views.py @@ -1,3 +1,6 @@ +from datetime import datetime +from logging import exception + from django.db import IntegrityError from rest_framework.permissions import ( IsAuthenticated, @@ -9,6 +12,13 @@ from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.encoding import force_bytes + +from GD.settings.base import PAYWALL +from core.idpay import IdPayRequest, IDPAY_PAYMENT_DESCRIPTION, IDPAY_CALL_BACK, IDPAY_STATUS_201 +from core.models import SingletonCompetition, EventService, Payment +from core.payping import PayPingRequest, PayPing_PAYMENT_DESCRIPTION, PayPing_CALL_BACK, PAYPING_STATUS_OK, \ + PayPingPeymentLinkGenerator +from core.serializers import EventServiceSerializer from tasks.tasks import ( send_team_requests_task, send_email_task, @@ -35,8 +45,8 @@ Team, ) from .serializers import ( - TeamSerialzer, - UserTeamSerialzier + TeamSerializer, + UserTeamSerializer ) from django.db import transaction from rest_framework.views import exception_handler @@ -61,7 +71,7 @@ class UserViewSet(ResponseGenericViewSet, serializer_class = CustomUserSerializer permission_classes_by_action = { 'list': [IsAdminUser], - 'retrive': [IsAuthenticated], + 'retrieve': [IsAuthenticated], 'destroy': [IsAuthenticated], 'update': [IsAdminUser], } @@ -156,7 +166,7 @@ def count(self, request): @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) def team(self, request): try: - serializer = TeamSerialzer( + serializer = TeamSerializer( get_user_model().objects.get(pk=request.user.pk).team) return self.set_response( data=serializer.data @@ -192,7 +202,7 @@ def available(self, request): def available_list(self, request): cmembers = get_user_model().objects.filter( team_role='NO', is_active=True, is_staff=False) - serialized = UserTeamSerialzier(cmembers, many=True) + serialized = UserTeamSerializer(cmembers, many=True) return self.set_response( data=serialized.data ) @@ -361,17 +371,16 @@ class TeamViewSet(ResponseGenericViewSet, mixins.ListModelMixin, mixins.RetrieveModelMixin): queryset = Team.objects.all() - serializer_class = TeamSerialzer + serializer_class = TeamSerializer permission_classes_by_action = { 'list': [IsAuthenticated], - 'retrive': [IsAuthenticated], + 'retrieve': [IsAuthenticated], 'destroy': [IsAdminUser], 'update': [IsAdminUser], } def retrieve(self, request, *args, **kwargs): - response_data = super(TeamViewSet, self).retrieve( - request, *args, **kwargs) + response_data = super(TeamViewSet, self).retrieve(request, *args, **kwargs) self.response_format["data"] = response_data.data self.response_format["status"] = 200 if not response_data.data: @@ -379,8 +388,7 @@ def retrieve(self, request, *args, **kwargs): return Response(self.response_format) def list(self, request, *args, **kwargs): - response_data = super(TeamViewSet, self).list( - request, *args, **kwargs) + response_data = super(TeamViewSet, self).list(request, *args, **kwargs) self.response_format["data"] = response_data.data self.response_format["status"] = 200 if not response_data.data: @@ -445,23 +453,113 @@ def create_team(self, request): } send_team_requests_task.delay(team_data) return self.set_response(data=self.serializer_class(team).data) + except get_user_model().DoesNotExist as e: return self.set_response(error=str(e), status=400, status_code=400) - # print(e2) - # return custom_exception_handler(e, None) + except Exception as e2: return self.set_response(error=str(e2), status=500, status_code=500) - # return self.set_response(error=str(e2)) - # print(e2) - # return custom_exception_handler(e2, None) - def get_permissions(self): - try: - # return permission_classes depending on `action` - return [permission() for permission in self.permission_classes_by_action[self.action]] - except KeyError: - # action is not set return default permission_classes - return [permission() for permission in self.permission_classes] + @action(methods=['POST'], detail=False, permission_classes=[IsAuthenticated]) + def enroll(self, request): + competition = SingletonCompetition.get_solo() + model_name = 'competition' + service_type = 'CP' + + if not competition.is_registration_active: + return self.set_response( + error=f"{model_name} is inactive", + status=406, + message=INACTIVE, + status_code=status.HTTP_406_NOT_ACCEPTABLE, + ) + if competition.get_remain_capacity() <= 0: + return self.set_response( + error=f"this {model_name} is full", + status=406, + message=CAPACITY_IS_FULL, + status_code=status.HTTP_406_NOT_ACCEPTABLE, + ) + + user = request.user + team = request.user.team + if not team or team.state != 'AC': + return self.set_response( + error=f"this team is not accepted", + status=406, + message=TEAM_NOT_ACCEPTED, + status_code=status.HTTP_406_NOT_ACCEPTABLE, + ) + + for member in team.members.all(): + args = {'user': member, model_name: competition, 'service_type': service_type, 'payment_state': 'CM'} + query = EventService.objects.filter(**args) + if query.exists(): + return self.set_response( + error=f"user has already enrolled in the {model_name}", + status=409, + message=USER_HAS_ALREADY_ENROLLED, + status_code=status.HTTP_409_CONFLICT, + ) + + args = {'user': user, model_name: competition, 'service_type': service_type, 'payment_state': 'PN'} + ev_service = EventService.objects.create(**args) + + if competition.cost < 1: + ev_service.payment_state = 'CM' + ev_service.save() + + return self.set_response( + message=SUCCESSFULLY_ADDED, + data=EventServiceSerializer(ev_service).data, + ) + else: + total_price = competition.cost + PayWallRequest = IdPayRequest if PAYWALL == "idpay" else PayPingRequest + payment = Payment.objects.create(total_price=total_price, user=user) + + result = PayWallRequest().create_payment( + order_id=payment.pk, + amount=int(total_price * 10 if PAYWALL == "idpay" else total_price), + desc=IDPAY_PAYMENT_DESCRIPTION if PAYWALL == 'idpay' else PayPing_PAYMENT_DESCRIPTION, + mail=user.email, + phone=user.phone_number, + callback=IDPAY_CALL_BACK if PAYWALL == 'idpay' else PayPing_CALL_BACK, + name=user.first_name + ) + + success_status = IDPAY_STATUS_201 if PAYWALL == "idpay" else PAYPING_STATUS_OK + if result['status'] == success_status: + ev_service.payment = payment + ev_service.save() + + payment.created_date = datetime.now() + payment.payment_link = ( + result)['link'] if PAYWALL == "idpay" else PayPingPeymentLinkGenerator(result['code']) + payment.save() + + if PAYWALL != 'idpay': + _status = result['status'] + _code = result['code'] + result = { + "link": PayPingPeymentLinkGenerator(_code), + "status": _status + } + return self.set_response(message=None, data=result, status_code=status.HTTP_200_OK) + else: + payment.delete() + return self.set_response( + message=CREATING_PAYMENT_UNSUCCESS, data=result, status_code=status.HTTP_400_BAD_REQUEST, + error=[{"error_code": result['status']}]) + + +def get_permissions(self): + try: + # return permission_classes depending on `action` + return [permission() for permission in self.permission_classes_by_action[self.action]] + except KeyError: + # action is not set return default permission_classes + return [permission() for permission in self.permission_classes] class VerifyTeamRequestView(generics.GenericAPIView): @@ -514,7 +612,7 @@ def get(self, request, tid, mid): 'message': TEAM_ACTIVED, 'error': None, 'status': 202, - 'data': UserTeamSerialzier(member).data + 'data': UserTeamSerializer(member).data } return Response(data=data, status=status.HTTP_202_ACCEPTED) except get_user_model().DoesNotExist as e: From 4bf50b2f4f19e244744bd3f6e94bf014eee839af Mon Sep 17 00:00:00 2001 From: MJ Akbari Date: Sat, 21 Sep 2024 16:01:58 +0330 Subject: [PATCH 2/3] debug --- core/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/admin.py b/core/admin.py index 6cac008..42e5453 100644 --- a/core/admin.py +++ b/core/admin.py @@ -225,7 +225,8 @@ class EventServiceAdmin(admin.ModelAdmin): 'fields': ( 'workshop', 'talk', - 'payment' + 'competition', + 'payment', ) } ) From f562fdbc3f2a97b846e9d8c91332dfa1f31c277c Mon Sep 17 00:00:00 2001 From: MJ Akbari Date: Sat, 21 Sep 2024 16:09:39 +0330 Subject: [PATCH 3/3] debug 2 --- user/admin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user/admin.py b/user/admin.py index 8b3c09b..f579180 100644 --- a/user/admin.py +++ b/user/admin.py @@ -114,11 +114,11 @@ def export_enrolled_teams(self, request, queryset): for team in queryset.all(): if team.get_payment_state() == "COMPLETED": for user in team.members.all(): - data.append([user.email, user.phone_number, user.first_name, team]) + data.append([user.email, user.phone_number, user.first_name, team.name]) data.sort(key=lambda x: x[3]) data.insert(0, headers) - return ExcelResponse(data=data, worksheet_name="Services", output_filename="services") + return ExcelResponse(data=data, worksheet_name="Teams", output_filename="teams") def payment_state(self, obj): return obj.get_payment_state()