Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/services/builtin_callout_cards.rb
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def materialized?(builtin_key)
# preview — a free event truly has no balance to preview, on a real ticket or
# a sample one, so there's nothing to click through.
def payment_card
return if self.class.config_gap(event, "payment")
return unless registration.cost_cents.to_i.positive?
billing = registration.billing_registration
due = billing.remaining_cost.to_i.positive?
Card.new(icon_class: "fa-solid fa-credit-card", color: due ? "orange" : "blue",
Expand Down
2 changes: 1 addition & 1 deletion app/views/event_registrations/_ticket.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
</div>
<% end %>

<% if event_registration.event.cost_cents.to_i > 0 && event_registration.status != "cancelled" && event_registration.remaining_cost > 0 && @checkout_payment_status != "paid" && !event_registration.transferred_out? %>
<% if event_registration.cost_cents.to_i > 0 && event_registration.status != "cancelled" && event_registration.remaining_cost > 0 && @checkout_payment_status != "paid" && !event_registration.transferred_out? %>
<div class="mt-2 space-y-3 text-center">
<% if event_registration.intends_to_pay? %>
<div>
Expand Down
14 changes: 7 additions & 7 deletions app/views/event_registrations/_transfer_notice.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
<div class="mb-4 flex items-start gap-3 rounded-lg border border-teal-200 bg-teal-50 px-4 py-3 text-sm text-teal-900">
<i class="fa-solid fa-right-to-bracket mt-0.5 text-teal-600"></i>
<div>
You transferred into <strong><%= event_registration.event.decorate.title_with_month_year %></strong>. Your earlier
payments, scholarship, and continuing-education records stay on your
<%= link_to "original registration", registration_ticket_path(source.slug), class: "font-semibold underline" %>
— any balance left is paid here, and your attendance and your certificate for these hours are earned at this event.
You transferred into <strong><%= event_registration.event.decorate.title_with_month_year %></strong>.<br>
Your earlier payments, scholarship, and continuing-education records stay on your
<%= link_to "original registration", registration_ticket_path(source.slug), class: "font-semibold underline" %>.<br>
Any balance left is paid here, and your attendance and certificate are earned at this event.
</div>
</div>
<% elsif event_registration.transferred_out? && (destination = event_registration.transferred_to_registration) %>
<div class="mb-4 flex items-start gap-3 rounded-lg border border-purple-200 bg-purple-50 px-4 py-3 text-sm text-purple-900">
<i class="fa-solid fa-right-from-bracket mt-0.5 text-purple-600"></i>
<div>
You transferred out of <strong><%= event_registration.event.decorate.title_with_month_year %></strong> to
<%= link_to "your new registration", registration_ticket_path(destination.slug), class: "font-semibold underline" %>.
Attend there and earn your certificate at that event, and pay any balance left there; your earlier
payments, scholarship, and continuing-education records remain here.
<%= link_to "your new registration", registration_ticket_path(destination.slug), class: "font-semibold underline" %>.<br>
Attend there and earn your certificate at that event, and pay any balance left there.<br>
Your earlier payments, scholarship, and continuing-education records remain here.
</div>
</div>
<% end %>
2 changes: 1 addition & 1 deletion app/views/events/callouts/scholarship.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<%# What the registrant owes. The award is allocated before it's accepted, so
while the agreement is pending this frames the balance as the choice the
buttons below are asking for rather than asserting the accepted one. %>
<% if @event.cost_cents.to_i.positive? && !@scholarship.agreement_declined? %>
<% if @event_registration.cost_cents.to_i.positive? && !@scholarship.agreement_declined? %>
<% owed = @event_registration.remaining_cost %>
<%# Support-requested is waiting on us, not an open accept/decline choice, so
state the balance plainly rather than framing it as the buttons' question. %>
Expand Down
11 changes: 11 additions & 0 deletions db/seeds/features/2026-11-05-pay-carried-balance-on-free-event.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: "Transferred registrants can pay a balance on a free event's ticket"
area: registration
display_status: admin_facing
released_on: 2026-11-05
pr_number: 2951
action_path: "/transfer_guide"
summary: >-
When someone transfers into a free event with a balance still owed, their new ticket now offers the
Pay button, so they can settle it and reach payment-gated callouts.
pro_tips:
- "The payment card only shows on that ticket if the event's Payment callout is published."
10 changes: 10 additions & 0 deletions spec/requests/events/registrations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
expect(response.body).to include(registration_ticket_path(destination.slug))
end

it "offers the Pay button when a balance carries into a free event" do
source = create(:event_registration, event: create(:event, cost_cents: 10_000), registrant: user.person, status: "transferred_out")
incoming = create(:event_registration, event: create(:event, cost_cents: 0), registrant: user.person,
transferred_from_registration: source)

get registration_ticket_path(incoming.slug)

expect(response.body).to include("Pay with Credit Card")
end

it "removes the Pay button on a transferred-out ticket (a normal unpaid reg keeps it) (#1944)" do
paid_event = create(:event, cost_cents: 10_000)
reg = create(:event_registration, event: paid_event, registrant: user.person)
Expand Down
11 changes: 11 additions & 0 deletions spec/services/builtin_callout_cards_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ def add_scholarship_form(event)
expect(card_titles(registration)).not_to include("Payment")
end

context "on a transferred-in ticket whose new event is free" do
let(:event) { create(:event, cost_cents: 0) }
let(:source) { create(:event_registration, event: create(:event, cost_cents: 10_000), status: "transferred_out") }

before { registration.update!(transferred_from_registration: source) }

it "shows the balance carried from the original event" do
expect(card(registration, "Make your payment").badge).to eq("$100 due")
end
end

context "on a transferred-out ticket" do
let(:event) { create(:event, cost_cents: 10_000) }
let!(:destination) do
Expand Down
Loading