InterSoccer Product Variations
Enhanced WooCommerce product variations with dynamic pricing, AJAX updates, and Elementor integration for InterSoccer camps and courses.
by Jeremy Lee · github.com/legit-ninja/intersoccer-product-variations
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/legit-ninja/intersoccer-product-variations/archive/refs/heads/master.zipReadme
InterSoccer Product Variations Plugin
Overview
This plugin enhances the WooCommerce booking system for InterSoccer Switzerland by managing complex product variations, dynamic pricing calculations, and sophisticated sibling discount systems. It supports three main product types: Camps (full-week and single-day), Courses (seasonal with prorated pricing), and Birthdays, with comprehensive admin interfaces and multilingual support.
Version
- Version: 2.9.1.1
- Release Date: September 1, 2026
Camp schedule meta (2.7.18+)
Camp variations store _camp_start_date, _camp_end_date, and _camp_week_index. Program Manager can edit/pre-fill these and seed them from camp-terms via wp intersoccer migrate-camp-dates. Parsing dates from pa_camp-terms remains a deprecated fallback during migration — see scratch/BACKLOG-remove-camp-terms-date-parse.md and .cursor/rules/camp-date-meta.mdc.
Program Manager + WPML (EN source of truth)
Edit the catalogue in the default language (EN). Program Manager create/duplicate still creates EN products only.
Use Sync all languages (WPML) on the Program Manager detail page (or the list bulk action on any selected programs) to create or refresh FR/DE product and variation translations via WPML/WCML, then copy InterSoccer catalogue data onto those siblings. Sync copies parent-level taxonomy attributes (shared EN slugs, including non-variation fields like pa_program-year / pa_girls-only) and variation schedule, attrs, prices, and course meta. Newly created/refreshed parents also receive the EN product status (draft/publish/private). Do not hand-edit English attributes onto FR/DE products — run Sync instead.
When FR/DE variation siblings already exist, saving camp schedule, venue, course time, camp times, price, facet repair, or course meta from Program Manager (or camp schedule writers) also copies those values onto the translated variations. New translations receive camp schedule keys on wpml_pro_translation_completed. Empty schedule reads on a translation fall back to default-language meta via intersoccer_get_camp_schedule() (raw intersoccer_get_camp_schedule_meta() stays local-only for the PM editor).
Catalogue year-roll (Bulk Duplicate)
- Seasons stay evergreen (
pa_program-season: Autumn/Winter/Spring/Summer). Year lives onpa_program-yearand in product titles — do not createAutumn 2027-style season terms. - Select rows → Bulk Actions Duplicate to year… → year/season fields appear beside the dropdown → Apply. Creates Draft clones (checked rows only) with year/season/title updates. Prices and camp/course dates are not copied — edit those, then Sync all languages (WPML), then Publish.
- List bulk actions (Refresh, Scaffold, Duplicate to year, Sync WPML) run one program at a time with a progress overlay (N of M, tallies, soft cancel). Without JavaScript, the classic full-page POST still works.
- Lifecycle: Publish = live; Private = retired sold years (orders still resolve); Draft = WIP. No auto-close of products/variations; roster close remains Reports/Rosters-only.
- Same-season course discounts and sibling season filters key on
season|pa_program-yearso evergreen Autumn does not cross-discount across years. - Program Manager status quick-edit fans out draft / publish / private to FR/DE product translations when they exist; Sync also applies EN status after create/refresh.
- Ops note: Obsidian
Fixing Products — Program Manager.
Features
Product Types & Variations
- Camps: Full-week bookings (e.g., CHF 500/week) and single-day selections with per-day pricing (e.g., CHF 55/day)
- Courses: Seasonal programs with automatic end-date calculation, holiday exclusions, and remaining session-based pricing
- Birthdays: Special event bookings with custom attributes
- Dynamic Attributes: Supports
pa_activity-type,pa_intersoccer-venues,pa_program-season,pa_age-group,pa_canton-region,pa_city,pa_booking-type,pa_course-day,pa_camp-terms,pa_days-of-week
Advanced Pricing System
- Camp Pricing: Full-week fixed pricing vs. single-day cumulative pricing based on selected days
- Course Pricing: Pro-rated pricing based on remaining sessions in the season, accounting for holidays and course schedules
- Real-time Calculations: AJAX-powered price updates in cart and checkout
- Currency Support: CHF denomination with WooCommerce integration
Comprehensive Discount System
- Camp Discounts:
- Sibling: 20% off 2nd child, 25% off 3rd+ children (counts children from previous orders within lookback)
- Progressive: Week 2 gets 10% off, Week 3+ gets 20% off (based on total weeks purchased)
- When sibling and progressive both apply to a line, the higher percent wins
- Full-week bookings only (single-day excluded)
- Course Discounts:
- Sibling: 20% off 2nd child, 30% off 3rd+ children (same season; prior orders included)
- Same-season: 50% off 2nd course for same child (different days)
- Retroactive: Applies even if first course was in previous order
- Tournament Discounts:
- Sibling: 20% off 2nd child, 30% off 3rd+ children (prior orders included)
- Multiple days: Day 1 = 30 CHF, Day 2+ = 20 CHF (2 days for 50 CHF)
- Retroactive: Applies even if first day was in previous order
- Precise Allocation: Context-aware discount application with cart validation
- Order Metadata: Discount details stored in order item metadata
- Configurable: All rates and features configurable via Admin UI
- Campaign Offers: Admin-configured time-boxed WooCommerce percent coupons (e.g. AUTUMN15 / TOGETHER20). Discount is the native coupon amount and may stack with sibling
set_price. Group offers collect joining name and guardian email at classic checkout. WooCommerce → InterSoccer Discounts → Campaign Offers. Single coupon code across EN/FR/DE.
Late Pickup System
- Camp Add-on: Optional late pickup service (18:00) with configurable pricing
- Flexible Options: Per-day selection or full-week pricing
- Admin Configuration: Customizable costs via WordPress options
- Multilingual: WPML integration for interface strings
Admin Interface
- Product Type Detection: Automatic detection via attributes or categories with caching
- Course Management: Start dates, total weeks, holiday exclusions, end-date calculation
- Variation Fields: Custom meta fields for course parameters
- Discount Management: Configure all discount rules, rates, and retroactive settings
- Order Lookback: Configurable period (1-24 months) for checking previous orders
- Debug Logging: Comprehensive error logging for troubleshooting
User Experience
- Variation Details: AJAX-powered variation information display
- Player Assignment: Integration with player management system
- Cart Updates: Real-time discount notifications and price adjustments
- Multilingual Support: WPML compatible (English, German, French)
Installation
- Upload the plugin files to the
/wp-content/plugins/directory. - Activate the plugin through the 'Plugins' menu in WordPress.
- Configure WooCommerce product attributes and variations.
- Set up InterSoccer-specific taxonomies (automatically registered).
- Configure late pickup pricing in WordPress options.
Development Workflow
- Code locally, deploy via SCP to
dev.intersoccer.legit.ninja. - Build Cypress E2E tests and PHPUnit unit tests.
- Commit to
github.com/legit-ninja/intersoccer-product-variations. - Tag releases (e.g.,
v1.10.8) with descriptive messages. - Upload zip to
updates.underdogunlimited.com. - Test on
staging.intersoccer.ch, then deploy to production.
Testing
- PHPUnit: Unit tests in
/tests/directory - Task Runner: Use
task testto run PHPUnit tests - Pre-commit Hooks: Automatic test execution on commits
Debugging
- Enable
WP_DEBUGandWP_DEBUG_LOGinwp-config.phpon Dev. - Check
wp-content/debug.logfor detailed error logs. - Use SSH/SCP for file access if activation fails.
- Review browser console logs and server logs on Dev.
Key Dependencies
- WooCommerce: Core e-commerce functionality
- WPML: Multilingual support (optional)
- PHPUnit: Testing framework
- Composer: Dependency management
Future Enhancements
- Weekly discount integration for multiple Summer Camps
- Google Sheets/Office365 export integration
- Advanced reporting and analytics
- API integrations for external booking systems
Key Metrics
- Booking completion rate (>90%)
- Price calculation accuracy in cart and orders
- Discount application success rate
- Multilingual content coverage
License
GPL-2.0 or later.
Contributors
- Jeremy Lee