Fix early-bird price blending and mislabeling; add contact-only events
- Early-bird pricing: RegistrationOption now tracks each purchase as a separate price tranche instead of overwriting a single price/quantity on repeat purchases, so buying more tickets after a tier expires no longer re-prices tickets already bought at the old price. Stock-limit checks, total-due calculation, and the Finance report's revenue-by- option are all tranche-aware; pages that showed one blended price per line now render/total each tranche. Viewing a pending/partially-paid registration (dashboard, detail page, or an event's registration list) now refreshes stale pricing on the spot instead of only at payment time. - Fixed the "(early bird)" dashboard label incorrectly firing on any line priced below the base option price (e.g. a plain cheaper variant) — it now checks the real applied-tier flag. - Added contact-only events (e.g. baptism): no registration/payment flow, shown on the public site with a "Contact us" popup instead of a Register button. Configurable via the admin event wizard. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -199,8 +199,9 @@ function PaymentsContent() {
|
||||
const now = new Date();
|
||||
const map: Record<string, { totalDue: number; totalPaid: number; outstanding: number }> = {};
|
||||
for (const r of list) {
|
||||
// totalDue uses priceSnapshot — not time-dependent
|
||||
const totalDue = (r.registrationOptions || []).reduce((sum: number, opt: any) => sum + optionUnitPrice(opt, null, now) * (opt.quantity || 0), 0);
|
||||
// Backend attaches a tranche-aware totalDueComputed (exact even when a line spans
|
||||
// multiple early-bird prices) — fall back to the old client-side estimate otherwise.
|
||||
const totalDue = r.totalDueComputed ?? (r.registrationOptions || []).reduce((sum: number, opt: any) => sum + optionUnitPrice(opt, null, now) * (opt.quantity || 0), 0);
|
||||
const totalPaid = (r.payments || []).reduce((s: number, p: any) => s + (p.amount || 0), 0);
|
||||
map[r.id] = { totalDue, totalPaid, outstanding: Math.max(0, totalDue - totalPaid) };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user