Skip to content

Commit b773ee0

Browse files
FinnIcklergregorbgdunkOnIT
authored
V2/V3 Compability Changes (#10127)
* add new routes * use new has_paid field * add history entry in payment controller * add route file that distinguishes between v2 and v3 routes * rename paymentStatus to paymentStatuses to indicate array * eslint * add V3 Polling Url * add competition to all routes * make available_refunds compatible with v3 * eslint * add missing comma * set V2_REGISTRATIONS_POLL_URL as optional in local * move add_history_entry to record_payment and refund_payment * fix comparison whoopsie * use better way to load registration in available_refunds * fix tests * fix v2 registration breaking * move order so we still return the right thing * fix v3 * Make V3 use the V1 export * expose routes in staging * allow routes to be exposed during asset compilation and on staging * fix acting user not being set for bulk update * fix acting user not loading properly * Fix form resetting V3 comps to V2 implicitly * fix registration deletion in v3 * fix waiting lists * don't remove if we are moving * fix tests for cancelled * fixed tests * added event ids to validate_update_status * fix rubocop * fix typo * fix another typo * fix pending scope * added test for registration count * fix polling * fix v3 polling * fix typo * add ? in registration?.payment * use new boolean * don't mark registration as finished if user has paid, but their registration is cancelled --------- Co-authored-by: Gregor Billing <gbilling@worldcubeassociation.org> Co-authored-by: Duncan <duncanonthejob@gmail.com>
1 parent b33b23d commit b773ee0

35 files changed

+326
-139
lines changed

.env.assets.production

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
WCA_REGISTRATIONS_URL=https://registration.worldcubeassociation.org
2-
WCA_REGISTRATIONS_POLL_URL=https://1rq8d7dif3.execute-api.us-west-2.amazonaws.com/v1/prod
2+
V2_REGISTRATIONS_POLL_URL=https://1rq8d7dif3.execute-api.us-west-2.amazonaws.com/v1/prod
3+
V3_REGISTRATIONS_POLL_URL=https://t7ni46t9jd.execute-api.us-west-2.amazonaws.com/v1/prod
34
ROOT_URL=https://www.worldcubeassociation.org

.env.assets.staging

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
WCA_REGISTRATIONS_URL=https://staging.registration.worldcubeassociation.org
2-
WCA_REGISTRATIONS_POLL_URL=https://1rq8d7dif3.execute-api.us-west-2.amazonaws.com/v1/staging
2+
V2_REGISTRATIONS_POLL_URL=https://1rq8d7dif3.execute-api.us-west-2.amazonaws.com/v1/staging
3+
V3_REGISTRATIONS_POLL_URL=https://t7ni46t9jd.execute-api.us-west-2.amazonaws.com/v1/staging
34
ROOT_URL=https://staging.worldcubeassociation.org

app/controllers/api/v1/registrations/registrations_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def bulk_update
7777
competition = Competition.find(params[:competition_id])
7878

7979
update_requests.each do |update|
80-
updated_registrations[update['user_id']] = Registrations::Lanes::Competing.update!(update, competition, @current_user)
80+
updated_registrations[update['user_id']] = Registrations::Lanes::Competing.update!(update, competition, @current_user.id)
8181
end
8282

8383
render json: { status: 'ok', updated_registrations: updated_registrations }

app/controllers/payment_controller.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ def available_refunds
55
if current_user
66
attendee_id = params.require(:attendee_id)
77
competition_id, user_id = attendee_id.split("-")
8+
competition = Competition.find(competition_id)
89

9-
ms_registration = MicroserviceRegistration.includes(:competition, :payment_intents)
10-
.find_by(competition_id: competition_id, user_id: user_id)
11-
return render status: :bad_request, json: { error: "Registration not found" } unless ms_registration.present?
10+
registration_scope = competition.uses_microservice_registrations? ? MicroserviceRegistration : Registration
11+
registration = registration_scope.includes(:payment_intents).find_by(competition: competition, user_id: user_id)
12+
13+
return render status: :bad_request, json: { error: "Registration not found" } unless registration.present?
1214

13-
competition = ms_registration.competition
1415
return render status: :unauthorized, json: { error: 'unauthorized' } unless current_user.can_manage_competition?(competition)
1516

16-
intents = ms_registration.payment_intents
17+
intents = registration.payment_intents
1718

1819
charges = intents.flat_map { |intent|
1920
payment_provider = CompetitionPaymentIntegration::INTEGRATION_RECORD_TYPES.invert[intent.payment_record_type]

app/models/competition.rb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,7 +1878,7 @@ def to_competition_info
18781878
force_comment_in_registration use_wca_registration external_registration_page guests_entry_fee_lowest_denomination guest_entry_status
18791879
information events_per_registration_limit],
18801880
methods: %w[url website short_name city venue_address venue_details latitude_degrees longitude_degrees country_iso2 event_ids registration_currently_open?
1881-
main_event_id number_of_bookmarks using_payment_integrations? uses_qualification? uses_cutoff? competition_series_ids registration_full?],
1881+
main_event_id number_of_bookmarks using_payment_integrations? uses_qualification? uses_cutoff? competition_series_ids registration_full? registration_version],
18821882
include: %w[delegates organizers],
18831883
}
18841884
self.as_json(options)
@@ -2569,10 +2569,31 @@ def set_form_data(form_data, current_user)
25692569
self.championships = []
25702570
end
25712571

2572+
# TODO: V3-Reg Remove this line and method implementation below
2573+
migration_reg_version = self.form_to_registration_version(form_data)
2574+
25722575
assign_attributes(Competition.form_data_to_attributes(form_data))
25732576

2574-
# TODO: Remove once v3 registrations (monolith integration) are implemented by default
2575-
self.registration_version = :v1 unless self.use_wca_registration
2577+
# TODO: V3-Reg Remove once v3 registrations (monolith integration) are implemented by default
2578+
self.registration_version = self.use_wca_registration? ? migration_reg_version : :v1
2579+
end
2580+
end
2581+
2582+
private def form_to_registration_version(form_data)
2583+
form_uses_new_registrations = form_data.dig('admin', 'usesNewRegistrationSystem')
2584+
2585+
if !form_uses_new_registrations
2586+
# If the form explicitly requested the old system, that's what you're gonna get.
2587+
:v1
2588+
elsif self.uses_new_registration_system?
2589+
# If we reached this point, we know that the form did not request the old system
2590+
# so that means the form requested the new version. Use whatever new version
2591+
# we're already on, to make sure the form doesn't ping-pong between V2 and V3
2592+
self.registration_version
2593+
else
2594+
# The form requested the new system, but we're not on the new system yet.
2595+
# Upgrade to whatever system works best
2596+
NEW_REG_SYSTEM_DEFAULT
25762597
end
25772598
end
25782599

app/models/registration.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# frozen_string_literal: true
22

33
class Registration < ApplicationRecord
4-
scope :pending, -> { where(accepted_at: nil).where(deleted_at: nil).where(is_competing: true) }
4+
scope :pending, -> { where(accepted_at: nil).where(deleted_at: nil).where(rejected_at: nil).where(waitlisted_at: nil).where(is_competing: true) }
55
scope :accepted, -> { where.not(accepted_at: nil).where(deleted_at: nil) }
66
scope :deleted, -> { where.not(deleted_at: nil) }
77
scope :rejected, -> { where.not(rejected_at: nil) }
8+
scope :waitlisted, -> { where.not(waitlisted_at: nil) }
89
scope :non_competing, -> { where(is_competing: false) }
910
scope :not_deleted, -> { where(deleted_at: nil) }
1011
scope :with_payments, -> { joins(:registration_payments).distinct }
@@ -177,6 +178,7 @@ def record_payment(
177178
receipt,
178179
user_id
179180
)
181+
add_history_entry({ payment_status: receipt.determine_wca_status, iso_amount: amount_lowest_denomination }, "user", user_id, 'Payment')
180182
registration_payments.create!(
181183
amount_lowest_denomination: amount_lowest_denomination,
182184
currency_code: currency_code,
@@ -192,6 +194,7 @@ def record_refund(
192194
refunded_registration_payment_id,
193195
user_id
194196
)
197+
add_history_entry({ payment_status: "refund", iso_amount: paid_entry_fees.cents - amount_lowest_denomination }, "user", user_id, 'Refund')
195198
registration_payments.create!(
196199
amount_lowest_denomination: amount_lowest_denomination.abs * -1,
197200
currency_code: currency_code,
@@ -238,7 +241,7 @@ def competing_status
238241
if accepted? || !is_competing?
239242
Registrations::Helper::STATUS_ACCEPTED
240243
elsif deleted?
241-
Registrations::Helper::STATUS_DELETED
244+
Registrations::Helper::STATUS_CANCELLED
242245
elsif rejected?
243246
Registrations::Helper::STATUS_REJECTED
244247
elsif pending?

app/webpacker/components/RegistrationsV2/Register/CompetingStep.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default function CompetingStep({
5555
}) {
5656
const maxEvents = competitionInfo.events_per_registration_limit ?? Infinity;
5757
const isRegistered = Boolean(registration);
58-
const hasPaid = registration?.payment.payment_status === 'succeeded';
58+
const hasPaid = registration?.payment?.has_paid;
5959
const dispatch = useDispatch();
6060

6161
const confirm = useConfirm();
@@ -89,7 +89,7 @@ export default function CompetingStep({
8989

9090
const queryClient = useQueryClient();
9191
const { mutate: updateRegistrationMutation, isPending: isUpdating } = useMutation({
92-
mutationFn: updateRegistration,
92+
mutationFn: (body) => updateRegistration(competitionInfo, body),
9393
onError: (data) => {
9494
const { error } = data.json;
9595
dispatch(setMessage(
@@ -117,7 +117,7 @@ export default function CompetingStep({
117117
});
118118

119119
const { mutate: createRegistrationMutation, isLoading: isCreating } = useMutation({
120-
mutationFn: submitEventRegistration,
120+
mutationFn: (body) => submitEventRegistration(competitionInfo, body),
121121
onError: (data) => {
122122
const { error } = data.json;
123123
dispatch(setMessage(

app/webpacker/components/RegistrationsV2/Register/PaymentStep.jsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import {
1010
Label,
1111
Segment,
1212
} from 'semantic-ui-react';
13-
import { paymentFinishUrl, wcaRegistrationUrl } from '../../../lib/requests/routes.js.erb';
13+
import { paymentFinishUrl, paymentTicketUrl } from '../../../lib/requests/routes.js.erb';
1414
import { useDispatch } from '../../../lib/providers/StoreProvider';
1515
import { setMessage } from './RegistrationMessage';
1616
import fetchWithJWTToken from '../../../lib/requests/fetchWithJWTToken';
1717
import Loading from '../../Requests/Loading';
1818
import i18n from '../../../lib/i18n';
1919
import useCheckboxState from '../../../lib/hooks/useCheckboxState';
2020
import AutonumericField from '../../wca/FormBuilder/input/AutonumericField';
21-
import RegistrationOverview from './RegistrationOverview';
21+
import getPaymentTicket from "../api/payment/get/getPaymentTicket";
2222

2323
export default function PaymentStep({
2424
competitionInfo,
@@ -37,7 +37,7 @@ export default function PaymentStep({
3737

3838
useEffect(() => {
3939
// TODO When we add per Event Payment this logic needs to also check if an additional payment is needed
40-
if (registration?.payment?.payment_status === 'succeeded') {
40+
if (registration?.payment?.has_paid) {
4141
nextStep();
4242
}
4343
}, [nextStep, registration]);
@@ -57,9 +57,7 @@ export default function PaymentStep({
5757
await elements.submit();
5858

5959
// Create the PaymentIntent and obtain clientSecret
60-
const { data } = await fetchWithJWTToken(`${wcaRegistrationUrl}/api/v1/${competitionInfo.id}/payment?donation_iso=${donationAmount}`, {
61-
method: 'GET',
62-
});
60+
const data = await getPaymentTicket(competitionInfo, donationAmount);
6361

6462
const { client_secret: clientSecret } = data;
6563

app/webpacker/components/RegistrationsV2/Register/Processing.jsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,21 @@ export default function Processing({ competitionInfo, user, onProcessingComplete
1111

1212
const { data } = useQuery({
1313
queryKey: ['registration-status-polling', user.id, competitionInfo.id],
14-
queryFn: async () => pollRegistrations(user.id, competitionInfo.id),
14+
queryFn: async () => pollRegistrations(user.id, competitionInfo),
1515
refetchInterval: REFETCH_INTERVAL,
1616
onSuccess: () => {
1717
setPollCounter(pollCounter + 1);
1818
},
1919
});
2020
useEffect(() => {
2121
if (
22-
data
23-
&& (data.status.payment === 'initialized'
24-
|| data.status.competing === 'pending')
22+
data && (data.status?.competing === 'pending' || !data.processing)
2523
) {
2624
onProcessingComplete();
2725
}
2826
}, [data, onProcessingComplete]);
2927
return (
30-
<Modal open={data?.status?.competing !== 'pending'} dimmer="blurring">
28+
<Modal open={data?.status?.competing !== 'pending' || !data?.processing} dimmer="blurring">
3129
<Modal.Header>
3230
{I18n.t('competitions.registration_v2.register.processing')}
3331
</Modal.Header>
@@ -37,7 +35,7 @@ export default function Processing({ competitionInfo, user, onProcessingComplete
3735
{I18n.t('competitions.registration_v2.register.processing_longer')}
3836
</Message>
3937
)}
40-
{data && data.queueCount > 500 && (
38+
{data && data.queueCount > 50 && (
4139
<Message warning>
4240
{I18n.t('competitions.registration_v2.register.processing_queue', {
4341
queueCount: data.queueCount,

app/webpacker/components/RegistrationsV2/Register/RegistrationOverview.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function RegistrationOverview({
4444
const queryClient = useQueryClient();
4545

4646
const { mutate: deleteRegistrationMutation, isPending: isDeleting } = useMutation({
47-
mutationFn: () => updateRegistration({
47+
mutationFn: () => updateRegistration(competitionInfo, {
4848
user_id: registration.user_id,
4949
competition_id: competitionInfo.id,
5050
competing: {

0 commit comments

Comments
 (0)