Skip to content

feat(sponsorships): multi-currency prices and slots for sponsorship tiers - #523

Merged
harshtandiya merged 6 commits into
developfrom
feat/sponsorship-tier-prices
Oct 2, 2026
Merged

harshtandiya merged 6 commits into
developfrom
feat/sponsorship-tier-prices

Conversation

@harshtandiya

Copy link
Copy Markdown
Collaborator

What changed

A tier's single price/currency moves into a new Buzz Price child table (currency, price; generic so ticket types can reuse it). The first row is the default. A tier needs at least one price, and no currency can repeat. The sponsor chooses which currency to pay in, and that row sets the gateway order's amount and currency. Tiers also get slots (0 or empty means unlimited). On the manage page, tiers become rows sorted oldest first.

  • Patch move_sponsorship_tier_price_to_prices (post_model_sync) copies the old columns into row 1. It reads them with frappe.qb, because Frappe leaves dropped columns in the table. It's idempotent.
  • get_payment_link now calls the gateway's validate_transaction_currency before recording the Event Payment. This affects bookings too. Paymob has no such method, so it's skipped.
  • Razorpay: non-INR orders need International Payments enabled on the account; Razorpay settles in INR.
  • Not fixed: the payments app's create_order always multiplies by 100, and our refund parsing divides by 100. Both are wrong for JPY (no decimals) and KWD/BHD/OMR (three decimals). Stick to two-decimal currencies for now.
  • PerkList now renders through a generic SortableList, which the new price list reuses.
  • Not done: nothing acts on a full tier yet; enquiries and payments still go through. Tracked in Sponsorship tiers: act on a tier's slots once it is full #522.

Demo

Tier rows
Tier drawer

Testing

Checks: sponsorship_tier, sponsorships (API, manage, forms), forms, event_sponsor, permissions, telemetry, communications, events and both patch test modules pass. Typecheck and lint are clean. I checked the drawer (add, reorder, save prices; slots) and the rows in the browser. E2E is left to CI. Not checked in the browser: the payment dialog's currency picker (covered by API tests). The patch test skips on sites that never had the old price column, CI included. test_buzz_event fails locally on the team fixture, before and after this change.

The drag handle, arrow-key reordering, remove and add buttons move into
SortableList, which renders each row through a slot. PerkList keeps only
its text input. Reorder and remove buttons are now labelled by position
("Reorder perk 2") instead of the perk text.
A tier's single price and currency move into a new Buzz Price child table
(currency, price), named generically so ticket types can use it later.
The first row is the tier's default. A tier must have at least one price,
and a currency can appear only once.

The tier drawer edits prices as a reorderable list with an "Add currency"
button, reusing SortableList. The Add Tier dialog still creates one price.
Cards, enquiry rows, the payment dialog and the public event page read the
first row, and tiers are now sorted by it in Python since the price column
is gone.

A patch copies each tier's old price and currency into its first row. The
"Normal" tier created with every event gets an INR 0 row.
When a tier has more than one price, the payment dialog shows a currency
select after a tier is picked, defaulting to the first row. The chosen
currency reaches create_sponsorship_payment_link, and the tier's matching
row sets the amount and currency of the gateway order. A currency the tier
has no price in is refused.

get_payment_link now asks the gateway controller to validate the currency
before recording the payment, so an unsupported currency fails with the
gateway's message instead of a failed order. Paymob's controller has no
such check and is skipped. This applies to booking payments too.
A tier can now cap how many sponsors it takes. Empty or 0 means any
number. The tier drawer edits it as a number field, which clamps
negative input to 0. The manage API returns it with each tier.

Nothing acts on a full tier yet; enquiries and payments still go
through. That is tracked in #522.
Tier cards become rows: name and perk count, the default price with the
other currencies under it, and slots taken with a progress bar, or
"Unlimited" when the tier has no cap. A full tier gets a Full badge.
Rows match the enquiry rows below them and use frappe-ui's Badge,
Progress and Icon. The hover background is limited to devices that can
hover, so a tap does not leave a row highlighted.

Tiers are listed oldest first instead of by price.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

…nk test needs

The Event Payment the test records links to a Payment Gateway named
Razorpay. Sites that never saved Razorpay Settings, CI included, have no
such record, so the insert failed link validation.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@harshtandiya
harshtandiya merged commit 7820a7c into develop Oct 2, 2026
8 checks passed
@harshtandiya
harshtandiya deleted the feat/sponsorship-tier-prices branch October 2, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant