From 67c9fc0fb94caef93e15aabb35c69ee0608d9cd7 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 13 Mar 2026 19:39:35 +0000 Subject: [PATCH] Update all pricing to new tiered structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registration: Early Bird €120/wk (before May 15), Standard €200/wk (before Jul 15), Last Minute €240/wk. Full month rates: €300/€500/€600. Accommodation: flat rates — Commons Hub multi €275/wk, double €350/wk; Herrnhof living €315/wk, triple €350/wk, single-in-double €420/wk, single €665/wk, couple €700/wk. Sponsorship pass values updated to match (based on last-minute rate). Co-Authored-By: Claude Opus 4.6 --- VOTC26-Sponsorship-Package.md | 14 +++---- api/application.js | 11 +++-- api/mollie.js | 57 ++++++++++++------------- apply.html | 73 ++++++++++++++++++++------------- index.html | 2 +- staging/sponsorships/index.html | 8 ++-- 6 files changed, 90 insertions(+), 75 deletions(-) diff --git a/VOTC26-Sponsorship-Package.md b/VOTC26-Sponsorship-Package.md index 26c1fdc..4faf9eb 100644 --- a/VOTC26-Sponsorship-Package.md +++ b/VOTC26-Sponsorship-Package.md @@ -22,7 +22,7 @@ | **Expected Attendance** | 60–100 participants | | **Format** | Four-week structured pop-up village | | **Organizers** | Commons Hub | -| **Pass Value** | €300/week (€1,200 for full 4 weeks) | +| **Pass Value** | €120–240/week depending on tier (€300–600 for full 4 weeks) | --- @@ -111,7 +111,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of - Logo on participant materials and signage **Engagement** -- **4 complimentary full passes** (4 weeks each — €4,800 value) +- **4 complimentary full passes** (4 weeks each — €2,400 value) - Dedicated 60-minute sponsored session slot - Private dinner with organizers and community leaders - First access to participant list (with consent) for networking @@ -133,7 +133,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of - Acknowledgment at ceremonies **Engagement** -- **2 complimentary full passes** (€2,400 value) +- **2 complimentary full passes** (€1,200 value) - 30-minute workshop or presentation slot - Access to participant introductions (with consent) @@ -152,7 +152,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of - Social media mention **Engagement** -- **1 complimentary full pass** (€1,200 value) +- **1 complimentary full pass** (€600 value) - Priority registration access **Content & Media** @@ -168,7 +168,7 @@ Four weeks of co-living creates relationships that last. Sponsors become part of - Social media thank-you post **Engagement** -- **1 discounted pass** (50% off — €600 value) +- **1 discounted pass** (50% off — €300 value) --- @@ -267,8 +267,8 @@ We'd love to discuss how a partnership could work for your organization. | Date | Milestone | |------|-----------| | **Now** | Sponsorship discussions open | -| **May 31, 2026** | Early bird registration closes | -| **July 31, 2026** | Regular registration closes | +| **May 15, 2026** | Early bird registration closes | +| **July 15, 2026** | Standard registration closes | | **August 1, 2026** | Final sponsor deliverables due | | **Aug 24 – Sep 20, 2026** | Valley of the Commons 2026 | | **October 2026** | Post-event report and media shared | diff --git a/api/application.js b/api/application.js index 14f4219..52b69ee 100644 --- a/api/application.js +++ b/api/application.js @@ -4,7 +4,7 @@ const { Pool } = require('pg'); const nodemailer = require('nodemailer'); const { syncApplication } = require('./google-sheets'); -const { createPayment, TICKET_LABELS, PRICE_PER_WEEK, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, PROCESSING_FEE_PERCENT, calculateAmount } = require('./mollie'); +const { createPayment, TICKET_LABELS, REGISTRATION_PRICING, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, PROCESSING_FEE_PERCENT, calculateAmount, getPricingTier } = require('./mollie'); const { addToListmonk } = require('./listmonk'); // Initialize PostgreSQL connection pool @@ -44,11 +44,14 @@ const confirmationEmail = (application) => { let accomHtml = ''; if (accomType && ACCOMMODATION_PRICES[accomType]) { const label = ACCOMMODATION_LABELS[accomType] || accomType; - const perWeek = ACCOMMODATION_PRICES[accomType]; + const accomPrices = ACCOMMODATION_PRICES[accomType]; + const accomDisplay = weeksCount === 4 + ? `${label} — €${accomPrices.perMonth} (full month)` + : `${label} — €${accomPrices.perWeek}/week × ${weeksCount} week${weeksCount > 1 ? 's' : ''} = €${pricing.accommodation}`; accomHtml = ` Accommodation: - ${label}
€${perWeek.toFixed(2)}/week × ${weeksCount} week${weeksCount > 1 ? 's' : ''} = €${pricing.accommodation} + ${accomDisplay} `; } @@ -72,7 +75,7 @@ const confirmationEmail = (application) => { - + ${accomHtml} diff --git a/api/mollie.js b/api/mollie.js index ba35ded..aa3e49f 100644 --- a/api/mollie.js +++ b/api/mollie.js @@ -29,41 +29,39 @@ const smtp = nodemailer.createTransport({ tls: { rejectUnauthorized: false }, }); -// Base registration price per week (EUR) -const PRICE_PER_WEEK = 300.00; +// Tiered registration pricing (EUR) +// Early Bird: before May 15 | Standard: before July 15 | Last Minute: after July 15 +const REGISTRATION_PRICING = { + early: { perWeek: 120, perMonth: 300 }, + standard: { perWeek: 200, perMonth: 500 }, + lastMin: { perWeek: 240, perMonth: 600 }, +}; // Processing fee percentage (added on top of subtotal) const PROCESSING_FEE_PERCENT = 0.02; -// Pricing tier — override with a fixed tier, or set to null to use date-based logic -const CURRENT_PRICING_TIER = 'standard'; - -// Date-based tier cutoffs (used when CURRENT_PRICING_TIER is null) -// Set ISO date strings, e.g. '2026-05-01' +// Date-based tier cutoffs const PRICING_TIER_DATES = { - earlyEnd: null, // before this date → 'early' - standardEnd: null, // before this date → 'standard'; after → 'lastMin' + earlyEnd: '2026-05-15', // before this date → 'early' + standardEnd: '2026-07-15', // before this date → 'standard'; after → 'lastMin' }; function getPricingTier() { - if (CURRENT_PRICING_TIER) return CURRENT_PRICING_TIER; const now = new Date(); - if (PRICING_TIER_DATES.earlyEnd && now < new Date(PRICING_TIER_DATES.earlyEnd)) return 'early'; - if (PRICING_TIER_DATES.standardEnd && now < new Date(PRICING_TIER_DATES.standardEnd)) return 'standard'; + if (now < new Date(PRICING_TIER_DATES.earlyEnd)) return 'early'; + if (now < new Date(PRICING_TIER_DATES.standardEnd)) return 'standard'; return 'lastMin'; } -// Accommodation prices (EUR) — tiered by duration and booking window -// 1week = per-week rate (multiply by weeks for 1–3 week stays) -// 4week = flat total for a full 4-week stay +// Accommodation prices (EUR) — flat rates (per week and per month/4-week) const ACCOMMODATION_PRICES = { - 'ch-multi': { '1week': { early: 395, standard: 475, lastMin: 515 }, '4week': { early: 1400, standard: 1600, lastMin: 1700 } }, - 'ch-double': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, - 'hh-living': { '1week': { early: 435, standard: 515, lastMin: 555 }, '4week': { early: 1560, standard: 1760, lastMin: 1860 } }, - 'hh-triple': { '1week': { early: 470, standard: 550, lastMin: 590 }, '4week': { early: 1700, standard: 1900, lastMin: 2000 } }, - 'hh-twin': { '1week': { early: 540, standard: 620, lastMin: 660 }, '4week': { early: 1980, standard: 2180, lastMin: 2280 } }, - 'hh-single': { '1week': { early: 785, standard: 865, lastMin: 905 }, '4week': { early: 2960, standard: 3160, lastMin: 3260 } }, - 'hh-couple': { '1week': { early: 940, standard: 1100, lastMin: 1180 }, '4week': { early: 3400, standard: 3800, lastMin: 4000 } }, + 'ch-multi': { perWeek: 275, perMonth: 1100 }, + 'ch-double': { perWeek: 350, perMonth: 1400 }, + 'hh-living': { perWeek: 315, perMonth: 1260 }, + 'hh-triple': { perWeek: 350, perMonth: 1400 }, + 'hh-twin': { perWeek: 420, perMonth: 1680 }, + 'hh-single': { perWeek: 665, perMonth: 2660 }, + 'hh-couple': { perWeek: 700, perMonth: 2800 }, }; // Human-readable labels for accommodation types @@ -72,7 +70,7 @@ const ACCOMMODATION_LABELS = { 'ch-double': 'Commons Hub — Bed in Double Room', 'hh-living': 'Herrnhof Villa — Bed in Living Room', 'hh-triple': 'Herrnhof Villa — Bed in Triple Room', - 'hh-twin': 'Herrnhof Villa — Bed in Twin Room', + 'hh-twin': 'Herrnhof Villa — Single Bed in Double Room', 'hh-single': 'Herrnhof Villa — Single Room', 'hh-couple': 'Herrnhof Villa — Couple Room', }; @@ -92,16 +90,15 @@ const TICKET_LABELS = { function calculateAmount(ticketType, weeksCount, accommodationType) { const weeks = weeksCount || 1; const tier = getPricingTier(); - const registration = PRICE_PER_WEEK * weeks; + const regPricing = REGISTRATION_PRICING[tier]; + + // Full month (4 weeks) gets the month rate; otherwise per-week + const registration = weeks === 4 ? regPricing.perMonth : regPricing.perWeek * weeks; let accommodation = 0; if (accommodationType && ACCOMMODATION_PRICES[accommodationType]) { const prices = ACCOMMODATION_PRICES[accommodationType]; - if (weeks === 4) { - accommodation = prices['4week'][tier]; - } else { - accommodation = prices['1week'][tier] * weeks; - } + accommodation = weeks === 4 ? prices.perMonth : prices.perWeek * weeks; } const subtotal = registration + accommodation; @@ -439,7 +436,7 @@ async function getPaymentStatus(req, res) { module.exports = { createPayment, handleWebhook, getPaymentStatus, - PRICE_PER_WEEK, PROCESSING_FEE_PERCENT, + REGISTRATION_PRICING, PROCESSING_FEE_PERCENT, ACCOMMODATION_PRICES, ACCOMMODATION_LABELS, TICKET_LABELS, calculateAmount, getPricingTier, }; diff --git a/apply.html b/apply.html index 38b290b..78c7637 100644 --- a/apply.html +++ b/apply.html @@ -655,13 +655,13 @@ @@ -672,31 +672,31 @@ @@ -776,21 +776,35 @@
Registration:€${PRICE_PER_WEEK}/week × ${weeksCount} week${weeksCount > 1 ? 's' : ''} = €${pricing.registration}${weeksCount === 4 ? `€${pricing.registration} (full month)` : `€${REGISTRATION_PRICING[pricing.tier].perWeek}/week × ${weeksCount} week${weeksCount > 1 ? 's' : ''} = €${pricing.registration}`} (${pricing.tier === 'early' ? 'Early Bird' : pricing.tier === 'standard' ? 'Standard' : 'Last Minute'} rate)