From b20898256763169f1b95d993d7a3a1ee3f97b45c Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Fri, 13 Sep 2024 19:33:42 +0530 Subject: [PATCH 01/15] team-reg: Add check for team fee in api --- server/api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/api.py b/server/api.py index 39797e16..780f7275 100644 --- a/server/api.py +++ b/server/api.py @@ -1481,6 +1481,9 @@ def add_team_registration( "action_href": f"/series/{tournament.event.series.slug}/", } + if tournament.event.team_fee > 0: + return 400, {"message": "Team registration can be done only after payment of team fee !"} + tournament.teams.add(team) return 200, tournament From 1ed24b3c239c090b47cec72597f2108815ee84ff Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Fri, 13 Sep 2024 23:12:59 +0530 Subject: [PATCH 02/15] transactions: Add player reg to order api --- server/transaction/api.py | 7 +++- server/transaction/schema.py | 6 +++ server/transaction/utils.py | 76 ++++++++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/server/transaction/api.py b/server/transaction/api.py index deae4946..149c5f98 100644 --- a/server/transaction/api.py +++ b/server/transaction/api.py @@ -34,6 +34,7 @@ ManualTransactionValidationFormSchema, PhonePeOrderSchema, PhonePeTransactionSchema, + PlayerRegistrationSchema, RazorpayCallbackSchema, RazorpayOrderSchema, RazorpayTransactionSchema, @@ -54,14 +55,16 @@ # Razorpay Transaction @router.post( - "/razorpay", response={200: RazorpayOrderSchema, 400: Response, 422: Response, 502: str} + "/razorpay", + response={200: RazorpayOrderSchema, 400: Response, 401: Response, 422: Response, 502: str}, ) def create_razorpay_transaction( request: AuthenticatedHttpRequest, order: AnnualMembershipSchema | EventMembershipSchema | GroupMembershipSchema - | TeamRegistrationSchema, + | TeamRegistrationSchema + | PlayerRegistrationSchema, ) -> tuple[int, str | message_response | dict[str, Any]]: return create_transaction(request, order, PaymentGateway.RAZORPAY) diff --git a/server/transaction/schema.py b/server/transaction/schema.py index 1dee5763..3cb8c2c9 100644 --- a/server/transaction/schema.py +++ b/server/transaction/schema.py @@ -139,3 +139,9 @@ class GroupMembershipSchema(Schema): class TeamRegistrationSchema(Schema): team_id: int event_id: int + + +class PlayerRegistrationSchema(Schema): + team_id: int + event_id: int + player_ids: list[int] diff --git a/server/transaction/utils.py b/server/transaction/utils.py index 0c9166b6..b4383822 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -9,7 +9,9 @@ from server.membership.models import Membership from server.season.models import Season from server.tournament.models import Event, Tournament +from server.tournament.utils import can_register_player_to_series_event from server.types import message_response +from server.utils import is_today_in_between_dates from .client import phonepe, razorpay from .models import ( @@ -23,6 +25,7 @@ AnnualMembershipSchema, EventMembershipSchema, GroupMembershipSchema, + PlayerRegistrationSchema, TeamRegistrationSchema, ) @@ -32,14 +35,15 @@ def create_transaction( order: AnnualMembershipSchema | EventMembershipSchema | GroupMembershipSchema - | TeamRegistrationSchema, + | TeamRegistrationSchema + | PlayerRegistrationSchema, gateway: PaymentGateway, transaction_id: str | None = None, ) -> tuple[int, str | message_response | dict[str, Any]]: user = request.user ts = round(time.time()) - if isinstance(order, GroupMembershipSchema): + if isinstance(order, GroupMembershipSchema | PlayerRegistrationSchema): players = Player.objects.filter(id__in=order.player_ids) player_ids = {p.id for p in players} if len(player_ids) != len(order.player_ids): @@ -103,6 +107,17 @@ def create_transaction( except Team.DoesNotExist: return 422, {"message": "Team does not exist!"} + if request.user not in team.admins.all(): + return 401, {"message": "Only team admins can register a team to a tournament !"} + + try: + tournament = Tournament.objects.get(event=event) + except Tournament.DoesNotExist: + return 400, {"message": "Tournament does not exist"} + + if tournament.status != Tournament.Status.REGISTERING: + return 400, {"message": "Team registration has closed, you can't register a team now !"} + if event.series and team not in event.series.teams.all(): return 400, { "message": "Team is not part of the series", @@ -120,6 +135,55 @@ def create_transaction( } receipt = f"team:{event.id}:{team.id}:{ts}" + elif isinstance(order, PlayerRegistrationSchema): + try: + team = Team.objects.get(id=order.team_id) + event = Event.objects.get(id=order.event_id) + tournament = Tournament.objects.get(event=event) + except (Event.DoesNotExist, Team.DoesNotExist, Tournament.DoesNotExist): + return 400, {"message": "Team/Event/Tournament does not exist"} + + if not is_today_in_between_dates( + from_date=tournament.event.player_registration_start_date, + to_date=tournament.event.player_registration_end_date, + ): + return 400, {"message": "Rostering has closed, you can't roster players now !"} + + if team not in tournament.teams.all(): + return 400, {"message": f"{team.name} is not registered for ${event.title} !"} + + if request.user not in team.admins.all(): + return 401, {"message": "Only team admins can roster players to the team"} + + if len(players) == 0: + return 400, {"message": "No players selected !"} + + if event.series: + for player in players: + can_register, error = can_register_player_to_series_event( + event=event, team=team, player=player + ) + if not can_register and error: + return 400, error + + start_date = event.start_date + end_date = event.end_date + amount = event.player_fee * len(players) + season = None + + player_names = ", ".join(sorted([player.user.get_full_name() for player in players])) + if len(player_names) > razorpay.RAZORPAY_NOTES_MAX: + player_names = player_names[:500] + "..." + + notes = { + "user_id": user.id, + "team_id": team.id, + "event_id": event.id, + "player_ids": str(player_ids), + "players": player_names, + } + receipt = f"player:{event.id}:{team.id}:{ts}" + else: # NOTE: We should never be here, thanks to request validation! pass @@ -181,13 +245,15 @@ def create_transaction( "players": [] if isinstance(order, TeamRegistrationSchema) else [player] - if not isinstance(order, GroupMembershipSchema) + if not isinstance(order, GroupMembershipSchema | PlayerRegistrationSchema) else players, "event": event, "season": season, "team": team, "type": RazorpayTransaction.TransactionTypeChoices.TEAM_REGISTRATION if isinstance(order, TeamRegistrationSchema) + else RazorpayTransaction.TransactionTypeChoices.PLAYER_REGISTRATION + if isinstance(order, PlayerRegistrationSchema) else RazorpayTransaction.TransactionTypeChoices.ANNUAL_MEMBERSHIP, } ) @@ -195,8 +261,10 @@ def create_transaction( RazorpayTransaction.create_from_order_data(data) transaction_user_name = user.get_full_name() description = ( - f"Team registration payment by {transaction_user_name}" + f"Team registration payment by {transaction_user_name} for {team.name if team is not None else ''}, event: {event.title if event is not None else ''}" if isinstance(order, TeamRegistrationSchema) + else f"Player registration payment by {transaction_user_name} for {player_names}, event: {event.title if event is not None else ''}" + if isinstance(order, PlayerRegistrationSchema) else f"Membership for {player.user.get_full_name()}" if not isinstance(order, GroupMembershipSchema) else f"Membership group payment by {transaction_user_name} for {player_names}" From f135ce208ea7629e3e525d8ef00f4bf232368ec0 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Fri, 13 Sep 2024 23:19:02 +0530 Subject: [PATCH 03/15] transactions: Add player reg to callback api --- server/transaction/api.py | 5 +++++ server/transaction/utils.py | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server/transaction/api.py b/server/transaction/api.py index 149c5f98..4a15edd5 100644 --- a/server/transaction/api.py +++ b/server/transaction/api.py @@ -44,6 +44,7 @@ create_transaction, list_transactions_by_type, update_transaction_player_memberships, + update_transaction_player_registrations, update_transaction_team_registration, ) @@ -115,6 +116,8 @@ def handle_razorpay_callback( update_transaction_player_memberships(transaction) elif transaction.type == RazorpayTransaction.TransactionTypeChoices.TEAM_REGISTRATION: update_transaction_team_registration(transaction) + elif transaction.type == RazorpayTransaction.TransactionTypeChoices.PLAYER_REGISTRATION: + update_transaction_player_registrations(transaction) return 200, transaction.players.all() @@ -190,6 +193,8 @@ def payment_webhook(request: HttpRequest) -> message_response: update_transaction_player_memberships(transaction) elif transaction.type == RazorpayTransaction.TransactionTypeChoices.TEAM_REGISTRATION: update_transaction_team_registration(transaction) + elif transaction.type == RazorpayTransaction.TransactionTypeChoices.PLAYER_REGISTRATION: + update_transaction_player_registrations(transaction) return {"message": "Webhook processed"} diff --git a/server/transaction/utils.py b/server/transaction/utils.py index b4383822..0ce55a93 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -8,7 +8,7 @@ from server.core.models import Player, Team, User from server.membership.models import Membership from server.season.models import Season -from server.tournament.models import Event, Tournament +from server.tournament.models import Event, Registration, Tournament from server.tournament.utils import can_register_player_to_series_event from server.types import message_response from server.utils import is_today_in_between_dates @@ -325,6 +325,18 @@ def update_transaction_team_registration( tournament.teams.add(transaction.team) +def update_transaction_player_registrations( + transaction: RazorpayTransaction, +) -> None: + registration = Registration( + event=transaction.event, + team=transaction.team, + player=transaction.player, + ) + + registration.save() + + def list_transactions_by_type( user: User, payment_type: PaymentGateway, user_only: bool = True, only_invalid: bool = False ) -> QuerySet[Model]: From 1928ea7085cf2da13852fa46a9048242778b1ace Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Fri, 13 Sep 2024 23:27:07 +0530 Subject: [PATCH 04/15] transactions: Check if player reg already exists for event --- server/transaction/utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/transaction/utils.py b/server/transaction/utils.py index 0ce55a93..00cddc69 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -166,6 +166,11 @@ def create_transaction( if not can_register and error: return 400, error + if Registration.objects.filter(event=event, player=player).exists(): + return 400, { + "message": f"Player - {player.user.get_full_name()} already registered for this event in another team !" + } + start_date = event.start_date end_date = event.end_date amount = event.player_fee * len(players) From 3f8ff3c51cb586a1544fffba61712956cc769e41 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 17:29:06 +0530 Subject: [PATCH 05/15] player-reg: Add razorpay payment for player fee --- .gitignore | 2 + frontend/.gitignore | 1 + frontend/src/components/RazorpayPayment.js | 4 +- frontend/src/components/roster/AddToRoster.js | 113 +++++++++++------- frontend/src/components/roster/View.js | 1 + 5 files changed, 77 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index 20081512..99f02daa 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,5 @@ cython_debug/ /.envrc /secrets /cron/ +/.vscode +/.DS_STORE \ No newline at end of file diff --git a/frontend/.gitignore b/frontend/.gitignore index b9bf98b5..d24a0dbd 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -1,2 +1,3 @@ node_modules/ static/bundle.js +/.DS_STORE diff --git a/frontend/src/components/RazorpayPayment.js b/frontend/src/components/RazorpayPayment.js index 8b0c61dd..ff0fd5b6 100644 --- a/frontend/src/components/RazorpayPayment.js +++ b/frontend/src/components/RazorpayPayment.js @@ -24,7 +24,9 @@ const RazorpayPayment = props => { const event_id = props.event?.id; const team_id = props.team?.id; const data = team_id - ? { team_id, event_id } // Team Registration + ? player_ids + ? { team_id, event_id, player_ids } // Player Registration + : { team_id, event_id } // Team Registration : props.annual ? player_ids ? { player_ids, season_id } // Group Membership diff --git a/frontend/src/components/roster/AddToRoster.js b/frontend/src/components/roster/AddToRoster.js index eb61f263..b83d08ea 100644 --- a/frontend/src/components/roster/AddToRoster.js +++ b/frontend/src/components/roster/AddToRoster.js @@ -11,7 +11,6 @@ import { } from "@tanstack/solid-table"; import clsx from "clsx"; import { Icon } from "solid-heroicons"; -import { handRaised } from "solid-heroicons/outline"; import { arrowRight, checkCircle, @@ -22,15 +21,12 @@ import { import { createEffect, createSignal, For, Show } from "solid-js"; import { ChevronLeft, ChevronRight, Spinner } from "../../icons"; -import { - addToRoster, - fetchUser, - searchSeriesRosterPlayers -} from "../../queries"; +import { addToRoster, searchSeriesRosterPlayers } from "../../queries"; import Info from "../alerts/Info"; import Modal from "../Modal"; import ErrorPopover from "../popover/ErrorPopover"; import SuccessPopover from "../popover/SuccessPopover"; +import RazorpayPayment from "../RazorpayPayment"; const AddToRoster = props => { let modalRef; @@ -39,7 +35,6 @@ const AddToRoster = props => { const [error, setError] = createSignal({}); const queryClient = useQueryClient(); - const userQuery = createQuery(() => ["me"], fetchUser); const addToRosterMutation = createMutation({ mutationFn: addToRoster, onSuccess: () => @@ -70,30 +65,6 @@ const AddToRoster = props => { return (
- reg.player.id) - .includes(userQuery.data?.player?.id) - } - > - - + + + p.id)} + amount={componentProps.playerFee * selectedPlayers().length} + setStatus={msg => { + return msg; + }} + successCallback={() => { + queryClient.invalidateQueries({ + queryKey: ["tournament-roster"] + }); + setStatus("Paid successfully!"); + }} + failureCallback={msg => { + setStatus(msg); + }} + /> +
+

Add Players to Roster

@@ -440,6 +466,7 @@ const AddPlayerRegistrationForm = componentProps => { +

{status()}

); diff --git a/frontend/src/components/roster/View.js b/frontend/src/components/roster/View.js index d09ea0ec..80001d8c 100644 --- a/frontend/src/components/roster/View.js +++ b/frontend/src/components/roster/View.js @@ -284,6 +284,7 @@ const Roster = () => { isPartOfSeries={ tournamentQuery.data?.event?.series ? true : false } + playerFee={tournamentQuery.data?.event?.player_fee || 0} /> From fc9ca8b3a9f8c785583c8b307fab4acceb5a9816 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 18:35:21 +0530 Subject: [PATCH 06/15] razorpay: Add more logs --- server/transaction/client/razorpay.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/server/transaction/client/razorpay.py b/server/transaction/client/razorpay.py index af81a07a..2236a9ae 100644 --- a/server/transaction/client/razorpay.py +++ b/server/transaction/client/razorpay.py @@ -1,11 +1,11 @@ import datetime +import logging import uuid from typing import Any import razorpay from django.conf import settings from django.utils.timezone import now -from requests.exceptions import RequestException from ..models import RazorpayTransaction from ..schema import RazorpayCallbackSchema @@ -15,6 +15,8 @@ RAZORPAY_NOTES_MAX = 512 RAZORPAY_DESCRIPTION_MAX = 255 +logger = logging.getLogger(__name__) + def create_order( amount: int, @@ -33,8 +35,12 @@ def create_order( } try: response = CLIENT.order.create(data=data) - except (RequestException, razorpay.errors.BadRequestError, razorpay.errors.ServerError) as e: - print(f"ERROR: Failed to connect to Razorpay with {e}") + except Exception as e: + logger.error("Failed to initiate Razorpay payment: %s", e) + return None + + if not response.success: + logger.error("Failed to initiate Razorpay payment: %s", response) return None response["key"] = settings.RAZORPAY_KEY_ID From 6fcb74e0113315cc8bcbb61b4cd320f9fc86426c Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 18:38:56 +0530 Subject: [PATCH 07/15] roster: Check if player already selected to pay --- frontend/src/components/roster/AddToRoster.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/roster/AddToRoster.js b/frontend/src/components/roster/AddToRoster.js index b83d08ea..844793ef 100644 --- a/frontend/src/components/roster/AddToRoster.js +++ b/frontend/src/components/roster/AddToRoster.js @@ -226,6 +226,9 @@ const AddPlayerRegistrationForm = componentProps => { when={ !(componentProps.roster || []) .map(reg => reg.player.id) + .includes(props.getValue()) && + !selectedPlayers() + .map(p => p.id) .includes(props.getValue()) } fallback={Added} From 3cee7ac381005865de71767f6e47cfed218bb3e2 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 19:06:29 +0530 Subject: [PATCH 08/15] transactions: Fix wrong type casting --- server/transaction/api.py | 4 ++-- server/transaction/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/transaction/api.py b/server/transaction/api.py index 4a15edd5..b6b51f89 100644 --- a/server/transaction/api.py +++ b/server/transaction/api.py @@ -64,8 +64,8 @@ def create_razorpay_transaction( order: AnnualMembershipSchema | EventMembershipSchema | GroupMembershipSchema - | TeamRegistrationSchema - | PlayerRegistrationSchema, + | PlayerRegistrationSchema + | TeamRegistrationSchema, ) -> tuple[int, str | message_response | dict[str, Any]]: return create_transaction(request, order, PaymentGateway.RAZORPAY) diff --git a/server/transaction/utils.py b/server/transaction/utils.py index 00cddc69..2bd32546 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -35,8 +35,8 @@ def create_transaction( order: AnnualMembershipSchema | EventMembershipSchema | GroupMembershipSchema - | TeamRegistrationSchema - | PlayerRegistrationSchema, + | PlayerRegistrationSchema + | TeamRegistrationSchema, gateway: PaymentGateway, transaction_id: str | None = None, ) -> tuple[int, str | message_response | dict[str, Any]]: From 1277e82aeee2aa09b853d99c123a23a5220e91e8 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 19:12:18 +0530 Subject: [PATCH 09/15] razorpay: Fix response log --- server/transaction/client/razorpay.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/transaction/client/razorpay.py b/server/transaction/client/razorpay.py index 2236a9ae..6c9dd955 100644 --- a/server/transaction/client/razorpay.py +++ b/server/transaction/client/razorpay.py @@ -39,10 +39,6 @@ def create_order( logger.error("Failed to initiate Razorpay payment: %s", e) return None - if not response.success: - logger.error("Failed to initiate Razorpay payment: %s", response) - return None - response["key"] = settings.RAZORPAY_KEY_ID response["order_id"] = response["id"] return response From 2bb7853d322b068e087e5c9dde7cf689aa28ea5f Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 19:34:33 +0530 Subject: [PATCH 10/15] transactions: Fix update player reg --- server/transaction/utils.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/server/transaction/utils.py b/server/transaction/utils.py index 2bd32546..745781a8 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -333,13 +333,14 @@ def update_transaction_team_registration( def update_transaction_player_registrations( transaction: RazorpayTransaction, ) -> None: - registration = Registration( - event=transaction.event, - team=transaction.team, - player=transaction.player, - ) + for player in transaction.players.all(): + registration = Registration( + event=transaction.event, + team=transaction.team, + player=player, + ) - registration.save() + registration.save() def list_transactions_by_type( From 85b292eefe3636fad9ca426b2b1af4c9f546295d Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 20:18:32 +0530 Subject: [PATCH 11/15] razorpay: Add callback for sdk failure --- frontend/src/components/RazorpayPayment.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/components/RazorpayPayment.js b/frontend/src/components/RazorpayPayment.js index ff0fd5b6..8e7c83d1 100644 --- a/frontend/src/components/RazorpayPayment.js +++ b/frontend/src/components/RazorpayPayment.js @@ -14,6 +14,11 @@ const RazorpayPayment = props => { props.setStatus( "Razorpay SDK failed to load. please check are you online?" ); + if (props.failureCallback) { + props.failureCallback( + "Razorpay SDK failed to load. please check are you online?" + ); + } } }); From 78f1008e79a93427f79a6b0f040236f96d934c82 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 20:18:55 +0530 Subject: [PATCH 12/15] roster: Refactor add to roster --- frontend/src/components/roster/AddToRoster.js | 181 ++++++------------ 1 file changed, 63 insertions(+), 118 deletions(-) diff --git a/frontend/src/components/roster/AddToRoster.js b/frontend/src/components/roster/AddToRoster.js index 844793ef..811fcd1c 100644 --- a/frontend/src/components/roster/AddToRoster.js +++ b/frontend/src/components/roster/AddToRoster.js @@ -11,13 +11,7 @@ import { } from "@tanstack/solid-table"; import clsx from "clsx"; import { Icon } from "solid-heroicons"; -import { - arrowRight, - checkCircle, - plus, - xCircle, - xMark -} from "solid-heroicons/solid"; +import { arrowRight, checkCircle, xCircle, xMark } from "solid-heroicons/solid"; import { createEffect, createSignal, For, Show } from "solid-js"; import { ChevronLeft, ChevronRight, Spinner } from "../../icons"; @@ -28,11 +22,16 @@ import ErrorPopover from "../popover/ErrorPopover"; import SuccessPopover from "../popover/SuccessPopover"; import RazorpayPayment from "../RazorpayPayment"; -const AddToRoster = props => { - let modalRef; +const AddToRoster = componentProps => { let successPopoverRef, errorPopoverRef, errorModalRef; const [status, setStatus] = createSignal(""); const [error, setError] = createSignal({}); + const [search, setSearch] = createSignal(""); + const [pagination, setPagination] = createSignal({ + pageIndex: 0, + pageSize: 5 + }); + const [selectedPlayers, setSelectedPlayers] = createSignal([]); const queryClient = useQueryClient(); const addToRosterMutation = createMutation({ @@ -43,8 +42,8 @@ const AddToRoster = props => { createEffect(function onMutationComplete() { if (addToRosterMutation.isSuccess) { - setStatus("Player added to the roster"); - successPopoverRef.showPopover(); + setStatus("Successfully added player to the roster"); + successPopoverRef?.showPopover(); } if (addToRosterMutation.isError) { try { @@ -53,9 +52,9 @@ const AddToRoster = props => { setStatus(mutationError.message); // Show error modal for long errors with a description, possibly an action button also if (mutationError.description) { - errorModalRef.showModal(); + errorModalRef?.showModal(); } else { - errorPopoverRef.showPopover(); + errorPopoverRef?.showPopover(); } } catch (err) { throw new Error(`Couldn't parse error object: ${err}`); @@ -63,106 +62,6 @@ const AddToRoster = props => { } }); - return ( -
- - Adding a new player to the roster} - close={() => modalRef.close()} - > - - - - -
- -
{status()}
-
-
- - -
- -
{status()}
-
-
- - errorModalRef.close()} - fullWidth={true} - title={ -
-
- -
-
{status()}
-
- } - > -
-
{error().description}
- -
-
-
- ); -}; - -const AddPlayerRegistrationForm = componentProps => { - const [search, setSearch] = createSignal(""); - const [pagination, setPagination] = createSignal({ - pageIndex: 0, - pageSize: 5 - }); - const [status, setStatus] = createSignal(); - const [selectedPlayers, setSelectedPlayers] = createSignal([]); - - const queryClient = useQueryClient(); - const addToRosterMutation = createMutation({ - mutationFn: addToRoster, - onSuccess: () => - queryClient.invalidateQueries({ queryKey: ["tournament-roster"] }) - }); - - createEffect(function onMutationComplete() { - if (addToRosterMutation.isSuccess) { - setStatus("Successfully added player to the roster"); - } - if (addToRosterMutation.isError) { - setStatus("Adding to the roster failed"); - } - }); - const handleAddToRoster = player => { if (componentProps.playerFee > 0) { setSelectedPlayers([...selectedPlayers(), player]); @@ -265,7 +164,7 @@ const AddPlayerRegistrationForm = componentProps => { }); return ( -
+
0}>

Player Registrations

@@ -310,16 +209,18 @@ const AddPlayerRegistrationForm = componentProps => { queryKey: ["tournament-roster"] }); setStatus("Paid successfully!"); + successPopoverRef?.showPopover(); }} failureCallback={msg => { + console.log(msg, componentProps.errorPopoverRef); + setStatus(msg); + errorPopoverRef?.showPopover(); }} />
-

- Add Players to Roster -

+

Search

Search players by name or email{" "} {

-

{status()}

+ +
+ +
{status()}
+
+
+ + +
+ +
{status()}
+
+
+ + errorModalRef.close()} + fullWidth={true} + title={ +
+
+ +
+
{status()}
+
+ } + > +
+
{error().description}
+ +
+
); }; From 991eb0cb8e805f6dc9ff971aaaa78a7b41ae5d96 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 20:29:28 +0530 Subject: [PATCH 13/15] transactions: Fix player reg validation --- server/transaction/utils.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/server/transaction/utils.py b/server/transaction/utils.py index 745781a8..ee0b2418 100644 --- a/server/transaction/utils.py +++ b/server/transaction/utils.py @@ -158,18 +158,18 @@ def create_transaction( if len(players) == 0: return 400, {"message": "No players selected !"} - if event.series: - for player in players: + for player in players: + if event.series: can_register, error = can_register_player_to_series_event( event=event, team=team, player=player ) if not can_register and error: return 400, error - if Registration.objects.filter(event=event, player=player).exists(): - return 400, { - "message": f"Player - {player.user.get_full_name()} already registered for this event in another team !" - } + if Registration.objects.filter(event=event, player=player).exists(): + return 400, { + "message": f"Player - {player.user.get_full_name()} already registered for this event in another team !" + } start_date = event.start_date end_date = event.end_date From f8fb8e25d20914b519fe340963029d5c8c54735e Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 20:40:31 +0530 Subject: [PATCH 14/15] razorpay: Fix error responses --- frontend/src/components/RazorpayPayment.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/RazorpayPayment.js b/frontend/src/components/RazorpayPayment.js index 8e7c83d1..660c1e78 100644 --- a/frontend/src/components/RazorpayPayment.js +++ b/frontend/src/components/RazorpayPayment.js @@ -77,11 +77,11 @@ const RazorpayPayment = props => { ); } else { - if (response.status === 422) { + if (response.status >= 400 && response.status < 500) { const error = await response.json(); props.setStatus(`Error: ${error.message}`); if (props.failureCallback) { - props.failureCallback(`Error: ${error.message}`); + props.failureCallback(error.message); } } else { const body = await response.text(); @@ -90,7 +90,7 @@ const RazorpayPayment = props => { ); if (props.failureCallback) { props.failureCallback( - `Error: ${response.statusText} (${response.status}) — ${body}` + `${response.statusText} (${response.status}) — ${body}` ); } } @@ -104,7 +104,7 @@ const RazorpayPayment = props => { ); if (props.failureCallback) { props.failureCallback( - `Error: ${response.error.code}: ${response.error.description}` + `${response.error.code}: ${response.error.description}` ); } }); @@ -112,11 +112,11 @@ const RazorpayPayment = props => { // window.location = data.redirect_url; } else { - if (response.status === 422) { + if (response.status >= 400 && response.status < 500) { const error = await response.json(); props.setStatus(`Error: ${error.message}`); if (props.failureCallback) { - props.failureCallback(`Error: ${error.message}`); + props.failureCallback(`${error.message}`); } } else { const body = await response.text(); @@ -125,7 +125,7 @@ const RazorpayPayment = props => { ); if (props.failureCallback) { props.failureCallback( - `Error: ${response.statusText} (${response.status}) — ${body}` + `${response.statusText} (${response.status}) — ${body}` ); } } @@ -136,7 +136,7 @@ const RazorpayPayment = props => { setLoading(false); props.setStatus(`Error: ${error}`); if (props.failureCallback) { - props.failureCallback(`Error: ${error}`); + props.failureCallback(`${error}`); } }); }; From eb15ed4baddf88da5b17d21af7e34f3abef87325 Mon Sep 17 00:00:00 2001 From: Jonathan Samuel Date: Sun, 15 Sep 2024 20:55:09 +0530 Subject: [PATCH 15/15] roster: Remove selected players after payment success --- frontend/src/components/roster/AddToRoster.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/roster/AddToRoster.js b/frontend/src/components/roster/AddToRoster.js index 811fcd1c..275685ed 100644 --- a/frontend/src/components/roster/AddToRoster.js +++ b/frontend/src/components/roster/AddToRoster.js @@ -210,6 +210,7 @@ const AddToRoster = componentProps => { }); setStatus("Paid successfully!"); successPopoverRef?.showPopover(); + setSelectedPlayers([]); }} failureCallback={msg => { console.log(msg, componentProps.errorPopoverRef);