NewPath-Consulting / warm

Pro Reports for Wild Apricot is a Google Data Studio connector that helps Wild Apricot administrators understand your organization’s membership engagement, renewal rates, and demographics. Trend your revenue and get expense analyses. Whatever your question, enjoy all the organized data you need at your fingertips to make the business decisions want.
https://newpathconsulting.com/warm
GNU General Public License v3.0
5 stars 4 forks source link

Add Event Registrations support #5

Closed asirota closed 4 years ago

asirota commented 4 years ago

add support for event registrations types and event registrations endpoints

miasmos commented 4 years ago

Is the user meant to provide an eventId? Which fields are of interest here?

asirota commented 4 years ago

The /EventRegistrations endpoint supports one of 3 parameters to configure. Only 1 of these 3 can be passed:

UserID - retrieves all registrations for the specified Contact's UserID

Event ID - retrieves all registrations for the specified Event's Event ID

Event ID Filter - retrieves all registrations for a comma delimited list of one or more Event IDs

These 2 boolean checkboxes can also be configured:

Include Registration Form Details - will return all registration form data as part of the event registration JSON -- this data is dynamic because registration forms can have custom fields (default off)

Include Waitlisted Registrations - if checked waitlisted registrations will be included (default off)

NOTE: there is no paging support since the mandatory setting 1 of 3 filters eliminates a majority of the records from the database for event registrations

The following records from the JSON should be retrieved

"Event": { "Name": "string", "StartDate": "string", "EndDate": "string", "Location": "string"

Dimension names: Event Name Event Start Date Event End Date Event Location

"Contact": {
  "Name": "string"

Dimension name: Registrant Name

"RegistrationType": {
  "Name": "string"
},

Dimension name: Registration Type

"GuestRegistrationsSummary": {
  "NumberOfGuests": 0,
  "NumberOfGuestsCheckedIn": 0,

Dimension names: Number of Guests Registered Number of Guests Checked In

"Organization": "string",
"IsCheckedIn": false,
"RegistrationFee": 0,
"PaidSum": 0,
"IsPaid": false,

Dimension names: Organization Registrant Checked In Registration Fee Paid Amount Registration Paid

-- these are the registration form fields, which are similarly structured as contact custom fields and are returned only if configured using the API parameter Include Registration Form Details

"RegistrationFields": [
  {
    "FieldName": "string",
    "Value": {}
  }

"RegistrationDate": "string",
"Memo": "string",
"IsGuestRegistration": false,
"OnWaitlist": false,

Dimension names: Registration Date Memo Is Guest Registration Is Waitlisted

miasmos commented 4 years ago

Completed initial implementation, just a few points of concern:

  1. I couldn't find NumberOfGuests or NumberOfCheckIns in the response, so I've omitted them for now.
  2. The fields only present when Include Registration Form Details is checked are still present in the schema when unchecked, and attempting to include them as a metric throws an error. More of a user pain point than anything.
  3. Event ID Filter is actually Event Registration ID filter. Filtering by event ID is not supported. Would you like this to be implemented for event registration ID?
asirota commented 4 years ago
  1. Ok -- I was reading the Swagger Hub description.
  2. So are you saying that no matter if the include registration form details is checked or unchecked the form details are returned in any case? If that's the case just return them in all circumstances and remove the checkbox. These to be sure are like contact custom fields and are all dimensions, not metrics.
  3. Go ahead and support filtering by Event Registration ID -- this may be useful when trying to just return registrations from one or more events. There may be a lot of data otherwise.
miasmos commented 4 years ago

Regarding 2, the data from the api is correct, it's excluding those fields from the response, but since our schema is the same whether it's checked or not, leaving it unchecked means that trying to access those fields in a report will throw an error. To fix this we'd need to separate these into 2 separate schemas, or we can just leave it how it is.

asirota commented 4 years ago

That's ok. Maybe just put a note near the checkbox for excluding this data that the custom fields will be included in the schema but without any data.

asirota commented 4 years ago

Can you move Event registrations object right under Events in the dropdown list on configuration?

asirota commented 4 years ago

I entered the Event ID on the configuration and it filtered for registrations only for that ID, what am I missing? I thought you said filtering by Events is not supported?

miasmos commented 4 years ago

By filtering by events I meant specifically with the $filter param. Filtering by a single event ID is supported via eventId.

asirota commented 4 years ago

Got it.

asirota commented 4 years ago

Where do the registration form fields appear in the scheme when I check the Include registration form details checkbox? I don't see them.

miasmos commented 4 years ago

Those are the RegistrationDate, Memo, IsGuestRegistration and IsWaitlisted fields.

asirota commented 4 years ago

The registration form fields should be all the form fields submitted as part of the registration. They are custom for each registration type. There can be custom field added to the registration as well.

2020-04-06_16-38-34

asirota commented 4 years ago

@stephenpoole I think you added the contact's common and membership fields into the event registration details. Instead it should be the event registration form records connected with the registration, which can be different for each event. For example

https://newpathconsulting.wildapricot.org/admin/events/details/?DetailsDisplayMode=View&eventId=3628796&selTab=2

You can see the common fields being collected on the registration and 3 custom fields Meal Choice Number of Guests Extra Guest Name

The registration form does not get any membership fields, just common fields and custom event registration form fields.

As I think about it -- the option to get event registration fields can ONLY be possible if your configuration parameter is on Event ID because only then can you can ensure that the same registration form fields are being collected.

Since each event can have a different registration form and custom fields so if you filter by UserID or Event Registration ID it would be impossible to grab the registration form/custom reg form fields since the schema would be different for different events.

miasmos commented 4 years ago
  1. I've made it so the option to Include registration form details only appears when Event ID is selected.
  2. I've modified the schema in this case to only include registration fields included in the api response. If the data is asymmetrical, it will fill in any empty fields with null to make it symmetrical.

For example:

[
    {
            "Id": 28998455,
            ...,
            "RegistrationFields": [
                {
                    "FieldName": "My First name",
                    "Value": "Carol",
                    "SystemCode": "FirstName"
                }
            ]
    },
    {
            "Id": 38998455,
            ...,
            "RegistrationFields": [
                {
                    "FieldName": "My First name",
                    "Value": "Carol",
                    "SystemCode": "FirstName"
                },
                {
                    "FieldName": "Middle Name",
                    "Value": "X",
                    "SystemCode": "custom-10380902"
                },
            ]
    }
]

In the above, 38998455 includes Middle Name, but 28998455 does not. 28998455 will be filled with a Middle Name of null so the data can still be viewed without errors. Note that I don't see a case where this happens, but in case it does in the future, it won't crash.

asirota commented 4 years ago

So on this registration, note the 3 custom fields added to this event under Event ID 3628796:

https://newpathconsulting.wildapricot.org/admin/events/registration-details/?DetailsDisplayMode=View&erid=29699886

Meal Choice : Vegeterian Number of guests: 1 x $100.00 (USD) = $100.00 (USD) Extra Guest Name: waitlist guest

These custom fields are not being returned in the schema when using the Event ID filter.

asirota commented 4 years ago

@stephenpoole so to get the meta data on all registration form fields configured and the custom fields you need to call the /events/{eventID} first to get the EventRegistrationFields:[] array which defines this information.

https://app.swaggerhub.com/apis-docs/WildApricot/wild-apricot_public_api/7.8.0#/Events/GetEventDetails

You'll see the structures for the event registration form which is what you should use for the dimensions:

"EventRegistrationFields": [
:
:
{
        "Id": 0,
        "Kind": "Custom",
        "AdminOnly": false,
        "FieldName": "New field",
        "Type": "MultipleChoice",
        "AllowedValues": [
          {
            "Id": 13104745,
            "Label": "New Item 1",
            "Value": "13104745",
            "SelectedByDefault": false,
            "Position": 0
          },
          {
            "Id": 13104746,
            "Label": "item 2",
            "Value": "13104746",
            "SelectedByDefault": false,
            "Position": 1
          },
          {
            "Id": 13104747,
            "Label": "item3",
            "Value": "13104747",
            "SelectedByDefault": false,
            "Position": 2
          }
        ],
        "IsSystem": false,
        "FieldInstructions": "",
        "Order": 6,
        "DisplayType": "CheckboxGroup",
        "SystemCode": "custom-11907503",
        "IsRequired": false
      }
miasmos commented 4 years ago

Added a call to /events/{eventId} to append registration fields when required.

Meal Choice : Vegeterian Number of guests: 1 x $100.00 (USD) = $100.00 (USD) Extra Guest Name: waitlist guest

These are now populated for 3628796.

asirota commented 4 years ago

Getting there @stephenpoole

these custom fields throw an error on event 3628796

Number of guests (extra charge calc) : this is an extra charge calculation field

The rules & terms field returns Null, even though registration ID 28820805 has true for this field:

https://newpathconsulting.wildapricot.org/admin/events/registration-details/?DetailsDisplayMode=View&erid=28820805

Test Rules is a Rules and Terms and is set to true on this event registration.

asirota commented 4 years ago

Testing Event Registration by User ID

Testing with userid 37415038, I included waitlisted registrations as part of the datasource configuration.

The following fields throw errors when included as dimensions

is Guest Registration
is Waitlisted
Memo
Registration Date
asirota commented 4 years ago

Testing with Event Registration by Event Registration ID Testing with event registration ID 28820805

The following fields throw errors when included as dimensions

is Guest Registration
is Waitlisted
Memo
Registration Date
asirota commented 4 years ago

Add Event Registration ID to the Event Registrations object

miasmos commented 4 years ago

Getting there @stephenpoole

these custom fields throw an error on event 3628796

Number of guests (extra charge calc) : this is an extra charge calculation field

The rules & terms field returns Null, even though registration ID 28820805 has true for this field:

https://newpathconsulting.wildapricot.org/admin/events/registration-details/?DetailsDisplayMode=View&erid=28820805

Test Rules is a Rules and Terms and is set to true on this event registration.

It seems Number of guests (extra charge calc) returns null from the api when calling /accounts/221748/eventregistrations?eventId=3628796&includeDetails=true { "FieldName": "Number of guests (extra charge calc)", "Value": null, "SystemCode": "custom-11479559" },

As for Test Rules, I'm not able to reproduce the issue you mention, all entries for 28820805 appear to have true/false values.

Testing Event Registration by User ID

Testing with userid 37415038, I included waitlisted registrations as part of the datasource configuration.

The following fields throw errors when included as dimensions

is Guest Registration
is Waitlisted
Memo
Registration Date

These fields are only included when "include registration form details" is checked. Since that checkbox isn't available for "User ID", I've added logic to append null for these fields so they don't throw errors.

Testing with Event Registration by Event Registration ID Testing with event registration ID 28820805

The following fields throw errors when included as dimensions

is Guest Registration
is Waitlisted
Memo
Registration Date

As above, these should no longer throw errors.

Add Event Registration ID to the Event Registrations object

I'm not sure I understand here, Event Registration ID is already an option within the Search type dropdown under the Event registrations object.

asirota commented 4 years ago

Thanks @stephenpoole — interesting about the extra charge calculation field. I’ll have to review one more time and maybe submit a ticket If the API is not returning data.

By ‘eventregistration ID’ I meant add a dimension to the result set so we can see which event registrations are being looked at, not the filter in the configuration which you already have as you said.

miasmos commented 4 years ago

Gotcha, I've added Registration ID to the schema

asirota commented 4 years ago

@stephenpoole it makes no sense to return null data for a limitation in the API that doesn't return these fields:

is Guest Registration
is Waitlisted
Memo
Registration Date

There is data there and it will confuse people when it returns null. They will trust the connector less if we are returning incorrect data.

Can we remove these 4 dimensions from the schema when filtering event registration by UserID or Event Registration ID? In particular Registration Date is very useful and I am surprised it is only return when filtering by event ID but not by Registration ID or User ID. Seems odd, and I'll post a feature request to the API to include these fields for all 3 variant filters of the EventRegistrations end point.

miasmos commented 4 years ago

I should have been more clear, when I said that the "include registration form details" checkbox is not available, I meant that we had not made it available. I can add it to both "User ID" and "Event registration ID".

Keep in mind though that by default, these fields will still be null when it is not checked.

asirota commented 4 years ago

Ah I see. But when we include this checkbox we cannot depend on the event registration form fields to be consistent across events or event registration IDs. Can we include just these 4 extra fields and not include the others we return?

asirota commented 4 years ago

Come to think of it, why don't we not offer the checkbox but just hard code to return form fields on these 2 filters and just include the fields we know will be there like these 4 fields?

asirota commented 4 years ago

Adding this checkbox will leave an impression that we will return event registration form fields but we cannot since they won't be consistent between events or event registration IDs. These 4 fields are the only consistent event registration form fields we have (even though they are not actually event registration form fields per se).

miasmos commented 4 years ago

I've removed the "include form details" checkbox, and the details are automatically included for the event type. The 4 fields are now populated for every registration event type.