Add PDF invoices/receipts with manual send, fix early-bird tier edit data loss
- Registration confirmations attach an invoice PDF (itemized breakdown, early-bird discount, balance due, Yoco pay-now link/QR) whenever a balance is outstanding; payment/donation confirmations attach a payment receipt PDF. Sent as an email attachment and, over WhatsApp, as the PDF itself with the existing message as its caption. - Users can also (re)send either document on demand: an "Invoice" button on the registration detail popup, and a "Receipt" button next to each payment there and on the Payment history page, each opening an Email/WhatsApp choice popup, via two new endpoints restricted to the registration/payment's own owner. - Fix: editing an event option's early-bird tiers deleted and recreated every tier for that option with brand-new ids, silently severing the appliedTierId link on all historical purchases (losing early-bird attribution and undercounting stock-limit usage) even for tiers the admin didn't touch. Tiers are now upserted by id. - Update the "My Events" help content and the API docs index for the new endpoints. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,8 @@ and this project follows [Semantic Versioning](https://semver.org/).
|
||||
### Added
|
||||
|
||||
- Events can now be marked "contact-only" (e.g. baptism) — they appear on the public events list/detail pages with a "Contact us" button (opening a popup with name/phone/email) instead of a Register button, and have no ticket options or registration flow. Configurable from a new toggle in the admin event wizard's Basic Details step.
|
||||
- Registration and payment notifications now include a branded PDF: registration confirmations attach an **invoice** (itemized breakdown, early-bird discount, balance due, and — when there's an outstanding balance — a clickable "pay now" link and QR code pointing at a Yoco checkout) whenever the registration isn't fully paid, and payment/donation confirmations attach a **payment receipt** (itemized breakdown plus the amount paid on that transaction). Sent as an email attachment and, over WhatsApp, as the PDF itself (with the existing message text as its caption) in place of the previous text-only send. Both documents pick up the org's configured name/logo/brand color from Site Settings → Branding.
|
||||
- The user dashboard's registration detail popup now has an "Invoice" button and, next to each payment, a "Receipt" button — both pop up a small Email/WhatsApp choice and (re)send that document on demand, via two new endpoints (`POST /api/registrations/:id/send-invoice`, `POST /api/payments/:id/send-receipt`), restricted to the registration/payment's own owner. The invoice works regardless of balance, showing "Paid in full" when nothing is owed. The Payment history page (`/dashboard/user/payments`) got the same per-payment "Receipt" button too.
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -18,6 +20,7 @@ and this project follows [Semantic Versioning](https://semver.org/).
|
||||
- An unpaid (or partially paid) registration's price only ever got refreshed when a payment was actually attempted — an early-bird tier that expired while tickets sat unpaid kept showing its old, no-longer-honoured price (and its "(early bird)" tag) indefinitely on the dashboard until the user tried to pay. Viewing a registration (dashboard, registration detail, or an event's registration list) now refreshes still-outstanding pricing on the spot, same as payment already did.
|
||||
- The user dashboard's registration detail popup listed one line per price tranche in raw creation order, so a ticket bought across several separate registrations (e.g. some early-bird, some not) showed as a wall of near-duplicate lines. It now merges tranches with the same item/price/tier into one line and groups early-bird lines together, separately from standard-price lines.
|
||||
- Registration confirmation, payment/donation, and reminder emails and WhatsApp messages computed "Total due"/"Balance" by loading a registration without its price tranches, so any line spanning more than one tranche (e.g. some tickets bought at the early-bird price, more added later at full price) fell back to charging the *entire* quantity at the most recent tranche's price — silently wiping out the early-bird discount from the outstanding balance shown to the user. These sends now load tranches and total each line the same tranche-aware way the dashboard already did; the itemized line amounts in those messages (which previously always showed the option's undiscounted base price) are now correct too.
|
||||
- Editing an event option's early-bird tiers (even just tweaking one tier's deadline or price) deleted and recreated *every* tier for that option with brand-new ids, including tiers the admin didn't touch. Since past purchases point at a specific tier by id, this silently severed that link on every edit — wiping the "early bird" attribution (and locked-in stock-limit counts, risking oversold tiers) off historical registrations that were never meant to change. Tiers are now upserted by id, so their identity — and everything referencing them — survives an edit; a tier is only ever removed if it's no longer in the saved list *and* has no purchase history against it.
|
||||
|
||||
## [1.7.0] - 2026-08-20
|
||||
|
||||
|
||||
Reference in New Issue
Block a user