This document describes how to configure the "MobileOut" registration category mapping for ASPET to exclude registrants from the RD (Results Direct) mobile app sync.
Registration Company Poseidon/Zenith Planion API RD Sync (Zenith) Results Direct
(Showcare) ↓ ↓ ↓ ↓
│ │ │ │ │
└──── pull ────────►│ │ │ │
└──── push ─────────►│ │ │
│ │ │
CECNFPEO table │ │
(regtype="MobileOut") │ │
│ │ │
└──── query ───────►│ │
└──── sync ───────►│
↓
PICKLIST (key=MEMTYP)
- desc = "MobileOut"
- exclude_mobile_app = 1
File: /home/bflorian/src/planion/api/psAPIRegConf.pas
- Receives registration data via
PostRegConfAPI - Stores registration type in
CECNFPEO.regtypefield - Uses
CheckRegTypeprocedure to look up Picklist mapping
Key Files:
| File | Purpose |
|---|---|
ps_data.py |
Queries Planstone data, including ps_get_regconf() and get_sql_query() |
rd_api.py |
RD API client with GET/POST/DELETE functions |
actions.py |
Sync orchestration including sync_regconf() and sync_delete() |
aspet.py |
ASPET-specific data transformations |
methods.py |
CLI interface for sync operations |
Location: /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/
The sync_delete() function in actions.py (lines 234-291) already handles deletions:
- Gets current RD roster via
rd_get_rosters(eventId) - Gets Planstone registrants via
ps_get_regconf()→ps_regconf_to_rd() - Computes diff:
rd_extra = set(rd_data.keys()) - set(ps_data.keys()) - Deletes extras from RD via
rd_delete()
Key insight: If we filter out "MobileOut" registrants in ps_get_regconf(), they won't appear in the Planstone data set, and sync_delete() will automatically remove them from RD.
Use the Registration Category Mapping screen (iframe injected into Planion) to create the "MobileOut" entry:
- Open the Registration Category Mapping configuration for the ASPET conference
- Add a new registration type with:
- Description:
MobileOut - Designation:
*(user-selected) - Mobile App Enabled: unchecked
- Exclude from Mobile App: checked (see UI Enhancement below)
- RD Attendee Role: leave blank (not synced to RD)
- Register in Planstone: checked (allow the registration)
- Description:
When the registration company sends data with "MobileOut", it flows through Planion:
File: /home/bflorian/src/planion/api/psAPIRegConf.pas
// The regtype value comes from the incoming JSON
RegType := APostContent.Values['regtype']; // "MobileOut"
// This gets stored in CECNFPEO.regtype
// CheckRegType looks up the Picklist entry to get designation and flagsNo changes needed to Planion if "MobileOut" is passed as the regtype value.
File: /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ps_data.py
The get_sql_query() function (lines 190-229) builds the SQL for ps_get_regconf(). Add filtering for exclude_mobile_app:
Current code (line 226):
desigmap_where = "and rd_attendee_roles is not null" if desigmap else "and cecnfpeo.registered = True"Updated code:
desigmap_where = "and rd_attendee_roles is not null and COALESCE(picklist.exclude_mobile_app, 0) = 0" if desigmap else "and cecnfpeo.registered = True"This adds AND COALESCE(picklist.exclude_mobile_app, 0) = 0 to filter out registrants whose registration type has exclude_mobile_app=1.
Once the query change is made, the existing sync_delete() function will automatically handle deletions:
File: /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/actions.py (lines 269-291)
# Existing code in sync_delete() - no changes needed
logger.info("checking: registrants")
rd_data = {s["externalKey"]: s for s in rd_get_rosters(eventId) if s["externalKey"] is not None}
rd_regconf = []
for c in conf.split(","):
ps_regconf = ps_get_regconf(db, account, c, eventId) # Now excludes MobileOut
rd_regconf += ps_regconf_to_rd(account, c, eventId, ps_regconf)
ps_data = {}
for c in conf.split(","):
ps_data.update({s["externalKey"]: s for s in rd_regconf if s["externalKey"] is not None})
rd_extra = set(rd_data.keys()) - set(ps_data.keys()) # MobileOut registrants are now "extra"
# ... deletes rd_extra from RDThe exclude_mobile_app field exists in the Picklist model (planion_picklist.py line 74) but is not currently exposed in the Backstage UI form.
File: /home/bflorian/src/products/zenith/poseidon/views/backstage/config/attendee_types.py
Add to AttendeeTypeForm:
class AttendeeTypeForm(forms.ModelForm):
# ... existing fields ...
exclude_mobile_app = forms.BooleanField(
required=False,
label="Exclude from Mobile App (Opt-Out)",
initial=False
)
class Meta:
model = Picklist
fields = ["desc", "desig", "mobile_app", "exclude_mobile_app", "rd_attendee_roles", "register_memtyp"]Template: /home/bflorian/src/products/zenith/poseidon/templates/backstage/config/attendee_type_form.html
Add checkbox in Options section (after the "Mobile App Enabled" checkbox):
<!-- Exclude from Mobile App (Opt-Out) -->
<div class="flex items-start">
<div class="flex h-6 items-center">
<input type="checkbox"
name="exclude_mobile_app"
id="{{ form.exclude_mobile_app.id_for_label }}"
{% if form.exclude_mobile_app.value %}checked{% endif %}
class="h-4 w-4 rounded border-gray-300 text-orange-600 focus:ring-orange-500">
</div>
<div class="ml-3">
<label for="{{ form.exclude_mobile_app.id_for_label }}" class="text-sm font-medium text-gray-700">
Exclude from Mobile App (Opt-Out)
</label>
<p class="text-xs text-gray-500">
Registrants with this type will be excluded from the RD mobile app sync.
If previously synced, they will be removed on the next sync cycle.
</p>
</div>
</div>1. POSEIDON/ZENITH pulls registration data from Showcare
- Receives regtype="MobileOut" for opted-out registrants
|
v
2. POSEIDON/ZENITH pushes to PLANION API
- Planion stores regtype="MobileOut" in CECNFPEO
- CheckRegType looks up Picklist entry for designation mapping
|
v
3. RD SYNC (Zenith) runs (scheduled)
- Queries CECNFPEO JOIN PICKLIST
- Filters: WHERE exclude_mobile_app = 0 (include in sync)
- Registrants with exclude_mobile_app = 1 are NOT in sync payload
- sync_delete() removes from RD any registrants not in current payload
|
v
4. RESULTS DIRECT MOBILE APP
- Only shows eligible registrants
- Opted-out users are automatically removed
- Add
exclude_mobile_appfield to UI form (attendee_types.py + template) - Modify
get_sql_query()in ps_data.py to filter onexclude_mobile_app - Create "MobileOut" entry via Registration Category Mapping screen with
exclude_mobile_app=1
- Send test registration with
regtype="MobileOut"via Planion API - Verify registration is stored in CECNFPEO with correct regtype
- Run
sync_regconfand verify "MobileOut" registrant is NOT sent to RD - Run
sync_deleteand verify previously-synced "MobileOut" registrants are DELETED from RD - Change "MobileOut" registrant back to normal type and run sync - verify they are added to RD
# View Planstone registrants (should NOT include MobileOut after code change)
python methods.py get_ps_regconf -a ASPET -c AM2026
# View RD roster (may still include MobileOut until sync_delete runs)
python methods.py get_rd_roster -a ASPET -c AM2026
# Run sync with deletion
python methods.py sync_all -a ASPET -c AM2026 -d 1
# Or run just the delete sync
python methods.py sync_delete -a ASPET -c AM2026| File | Location | Purpose |
|---|---|---|
| Planion | ||
| psAPIRegConf.pas | /home/bflorian/src/planion/api/ |
Registration API - stores regtype in CECNFPEO |
| Zenith RD Integration | ||
| ps_data.py | /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ |
KEY FILE - get_sql_query() needs exclude_mobile_app filter (line 226) |
| actions.py | /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ |
sync_delete() handles RD deletions (lines 234-291) |
| rd_api.py | /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ |
RD API client (GET/POST/DELETE) |
| aspet.py | /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ |
ASPET-specific data transformations |
| methods.py | /home/bflorian/src/products/zenith/poseidon/integrations/resultsdirect/ |
CLI for sync operations |
| Zenith Models | ||
| planion_picklist.py | /home/bflorian/src/products/zenith/poseidon/models/planion/ |
Picklist model with exclude_mobile_app field (line 74) |
| planion_cecnfpeo.py | /home/bflorian/src/products/zenith/poseidon/models/planion/ |
Registration records with regtype field |
| Zenith UI (optional) | ||
| attendee_types.py | /home/bflorian/src/products/zenith/poseidon/views/backstage/config/ |
UI form for Registration Category Mapping |
| attendee_type_form.html | /home/bflorian/src/products/zenith/poseidon/templates/backstage/config/ |
UI template for the form |