pike13 0.1.0.beta → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -116
  3. data/README.md +1222 -315
  4. data/lib/pike13/api/v2/account.rb +19 -0
  5. data/lib/pike13/api/v2/desk/booking.rb +10 -0
  6. data/lib/pike13/api/v2/desk/business.rb +2 -1
  7. data/lib/pike13/api/v2/desk/event_occurrence.rb +2 -2
  8. data/lib/pike13/api/v2/desk/person.rb +5 -3
  9. data/lib/pike13/api/v2/desk/plan.rb +2 -2
  10. data/lib/pike13/api/v2/desk/plan_product.rb +2 -2
  11. data/lib/pike13/api/v2/desk/service.rb +2 -2
  12. data/lib/pike13/api/v2/desk/visit.rb +2 -2
  13. data/lib/pike13/api/v2/front/branding.rb +2 -1
  14. data/lib/pike13/api/v2/front/business.rb +2 -1
  15. data/lib/pike13/api/v2/front/event_occurrence.rb +2 -2
  16. data/lib/pike13/api/v2/front/plan_product.rb +2 -2
  17. data/lib/pike13/api/v2/front/service.rb +2 -2
  18. data/lib/pike13/api/v2/front/visit.rb +2 -2
  19. data/lib/pike13/api/v3/desk/base.rb +46 -0
  20. data/lib/pike13/api/v3/desk/clients.rb +180 -0
  21. data/lib/pike13/api/v3/desk/enrollments.rb +203 -0
  22. data/lib/pike13/api/v3/desk/event_occurrence_staff_members.rb +170 -0
  23. data/lib/pike13/api/v3/desk/event_occurrences.rb +154 -0
  24. data/lib/pike13/api/v3/desk/invoice_item_transactions.rb +189 -0
  25. data/lib/pike13/api/v3/desk/invoice_items.rb +193 -0
  26. data/lib/pike13/api/v3/desk/invoices.rb +167 -0
  27. data/lib/pike13/api/v3/desk/monthly_business_metrics.rb +151 -0
  28. data/lib/pike13/api/v3/desk/pays.rb +128 -0
  29. data/lib/pike13/api/v3/desk/person_plans.rb +265 -0
  30. data/lib/pike13/api/v3/desk/staff_members.rb +127 -0
  31. data/lib/pike13/api/v3/desk/transactions.rb +169 -0
  32. data/lib/pike13/http_client.rb +4 -1
  33. data/lib/pike13/http_client_v3.rb +101 -0
  34. data/lib/pike13/validators.rb +136 -0
  35. data/lib/pike13/version.rb +1 -1
  36. data/lib/pike13.rb +26 -7
  37. metadata +17 -2
  38. data/lib/pike13/api/v2/account/me.rb +0 -20
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Pike13 Ruby Client
2
2
 
3
- A Ruby gem for interacting with the [Pike13 Core API](https://developer.pike13.com/docs/api/v2).
3
+ A Ruby gem for interacting with the Pike13 API, supporting both:
4
+ - **[Core API](https://developer.pike13.com/docs/api/v2)** - CRUD operations for managing people, events, invoices, and more
5
+ - **[Reporting API](https://developer.pike13.com/docs/reporting/v3)** - Advanced analytics and reporting queries
4
6
 
5
7
  ## Installation
6
8
 
@@ -30,63 +32,94 @@ end
30
32
 
31
33
  ## Usage
32
34
 
33
- The Pike13 API is organized into three namespaces:
34
-
35
- - **Account** - Account-level operations (not scoped to a business)
36
- - **Desk** - Staff interface operations (full access)
37
- - **Front** - Client interface operations (limited access)
35
+ The gem supports two API versions with different capabilities:
36
+
37
+ ### Core API - CRUD Operations
38
+
39
+ Three namespaces for managing your business data:
40
+
41
+ - **Account** (`Pike13::Account`) - Account-level operations (not scoped to a business)
42
+ - **Desk** (`Pike13::Desk`) - Staff interface operations (full read/write access)
43
+ - **Front** (`Pike13::Front`) - Client interface operations (limited access for customer-facing apps)
44
+
45
+ ### Reporting API - Analytics & Insights
46
+
47
+ - **Reporting** (`Pike13::Reporting`) - Advanced query-based analytics with 12 comprehensive reporting endpoints
48
+
49
+ ## Table of Contents
50
+
51
+ - [Account Resources](#account-resources)
52
+ - [Desk Resources](#desk-resources)
53
+ - [People](#people)
54
+ - [Business](#business)
55
+ - [Events & Event Occurrences](#events--event-occurrences)
56
+ - [Appointments](#appointments)
57
+ - [Bookings](#bookings)
58
+ - [Visits](#visits)
59
+ - [Locations, Services, Staff](#locations-services-staff)
60
+ - [Plans & Products](#plans--products)
61
+ - [Invoices & Payments](#invoices--payments)
62
+ - [Financial Settings](#financial-settings)
63
+ - [Notes](#notes)
64
+ - [Make-Ups](#make-ups)
65
+ - [Waitlist](#waitlist)
66
+ - [Custom Fields](#custom-fields)
67
+ - [Person-Related Resources](#person-related-resources)
68
+ - [Front Resources](#front-resources)
69
+ - [Business & Branding](#business--branding)
70
+ - [People](#people-1)
71
+ - [Events & Event Occurrences](#events--event-occurrences-1)
72
+ - [Appointments](#appointments-1)
73
+ - [Bookings](#bookings-1)
74
+ - [Visits](#visits-1)
75
+ - [Locations, Services, Staff](#locations-services-staff-1)
76
+ - [Plans & Products](#plans--products-1)
77
+ - [Invoices & Payments](#invoices--payments-1)
78
+ - [Notes](#notes-1)
79
+ - [Waitlist](#waitlist-1)
80
+ - [Person-Related Resources](#person-related-resources-1)
81
+ - [Reporting Resources](#reporting-resources)
82
+ - [Monthly Business Metrics](#monthly-business-metrics)
83
+ - [Clients](#clients)
84
+ - [Transactions](#transactions)
85
+ - [Invoices](#invoices-1)
86
+ - [Enrollments](#enrollments)
87
+ - [Event Occurrences](#event-occurrences)
88
+ - [Event Occurrence Staff Members](#event-occurrence-staff-members)
89
+ - [Invoice Items](#invoice-items)
90
+ - [Invoice Item Transactions](#invoice-item-transactions)
91
+ - [Pays](#pays)
92
+ - [Person Plans](#person-plans)
93
+ - [Staff Members](#staff-members)
94
+ - [Error Handling](#error-handling)
95
+ - [Development](#development)
96
+ - [License](#license)
38
97
 
39
98
  ### Account Resources
40
99
 
41
- Account-level resources for managing your Pike13 account.
100
+ Account-level operations for managing your Pike13 account.
42
101
 
43
102
  ```ruby
44
- # Get current account
45
- Pike13::Account::Me.me
46
-
47
- # List all businesses
48
- Pike13::Account::Business.all
49
-
50
- # Get all people
51
- Pike13::Account::Person.all
52
-
53
- # Password reset
54
- Pike13::Account::Password.create(email: "user@example.com")
55
-
56
- # Email confirmation
57
- Pike13::Account::Confirmation.create(confirmation_token: "token")
103
+ Pike13::Account.me # Get current account
104
+ Pike13::Account::Business.all # List all businesses
105
+ Pike13::Account::Person.all # Get all people
106
+ Pike13::Account::Password.create(email: "user@example.com") # Password reset
107
+ Pike13::Account::Confirmation.create(confirmation_token: "token") # Email confirmation
58
108
  ```
59
109
 
60
- ### Desk Resources (Staff Interface)
110
+ ### Desk Resources
61
111
 
62
112
  Full staff interface with read/write access to all resources.
63
113
 
64
114
  #### People
65
115
 
66
116
  ```ruby
67
- # List all people
68
- Pike13::Desk::Person.all
69
-
70
- # Find a person
71
- Pike13::Desk::Person.find(123)
72
-
73
- # Get authenticated user
74
- Pike13::Desk::Person.me
75
-
76
- # Search people
77
- Pike13::Desk::Person.search("john")
78
-
79
- # Create a person
80
- Pike13::Desk::Person.create(
81
- first_name: "John",
82
- last_name: "Doe",
83
- email: "john@example.com"
84
- )
85
-
86
- # Update a person
117
+ Pike13::Desk::Person.all # List all people
118
+ Pike13::Desk::Person.find(123) # Find a person
119
+ Pike13::Desk::Person.me # Get authenticated user
120
+ Pike13::Desk::Person.search("john") # Search people
121
+ Pike13::Desk::Person.create(first_name: "John", last_name: "Doe", email: "john@example.com")
87
122
  Pike13::Desk::Person.update(123, first_name: "Jane")
88
-
89
- # Delete a person
90
123
  Pike13::Desk::Person.destroy(123)
91
124
  ```
92
125
 
@@ -100,50 +133,21 @@ Pike13::Desk::Business.find
100
133
  #### Events & Event Occurrences
101
134
 
102
135
  ```ruby
103
- # List events
104
- Pike13::Desk::Event.all
105
-
106
- # Find event
107
- Pike13::Desk::Event.find(100)
108
-
109
- # List event occurrences
136
+ Pike13::Desk::Event.all # List events
137
+ Pike13::Desk::Event.find(100) # Find event
110
138
  Pike13::Desk::EventOccurrence.all(from: "2025-01-01", to: "2025-01-31")
111
-
112
- # Find occurrence
113
- Pike13::Desk::EventOccurrence.find(789)
114
-
115
- # Get occurrence summary
116
- Pike13::Desk::EventOccurrence.summary
117
-
118
- # Check enrollment eligibility
139
+ Pike13::Desk::EventOccurrence.find(789) # Find occurrence
140
+ Pike13::Desk::EventOccurrence.summary # Get occurrence summary
119
141
  Pike13::Desk::EventOccurrence.enrollment_eligibilities(id: 789)
120
142
 
121
- # List event occurrence notes
143
+ # Event occurrence notes
122
144
  Pike13::Desk::EventOccurrenceNote.all(event_occurrence_id: 789)
123
-
124
- # Find event occurrence note
125
- Pike13::Desk::EventOccurrenceNote.find(event_occurrence_id: 789, id: 1)
126
-
127
- # Create event occurrence note
128
- Pike13::Desk::EventOccurrenceNote.create(
129
- event_occurrence_id: 789,
130
- attributes: { body: "This is a note" }
131
- )
132
-
133
- # Update event occurrence note
134
- Pike13::Desk::EventOccurrenceNote.update(
135
- event_occurrence_id: 789,
136
- id: 1,
137
- attributes: { body: "Updated note" }
138
- )
139
-
140
- # Delete event occurrence note
145
+ Pike13::Desk::EventOccurrenceNote.create(event_occurrence_id: 789, attributes: { note: "This is a note", subject: "Note Subject" })
146
+ Pike13::Desk::EventOccurrenceNote.update(event_occurrence_id: 789, id: 1, attributes: { note: "Updated note" })
141
147
  Pike13::Desk::EventOccurrenceNote.destroy(event_occurrence_id: 789, id: 1)
142
148
 
143
- # List visits for an event occurrence
149
+ # Visits and waitlist
144
150
  Pike13::Desk::EventOccurrenceVisit.all(event_occurrence_id: 789)
145
-
146
- # List waitlist entries for an event occurrence
147
151
  Pike13::Desk::EventOccurrenceWaitlistEntry.all(event_occurrence_id: 789)
148
152
  ```
149
153
 
@@ -170,34 +174,21 @@ Pike13::Desk::Appointment.available_slots_summary(
170
174
 
171
175
  #### Bookings
172
176
 
177
+ **Note:** Creating bookings requires an `idempotency_token` parameter to prevent duplicate bookings.
178
+
173
179
  ```ruby
174
- # Find booking
175
180
  Pike13::Desk::Booking.find(123)
176
-
177
- # Create booking
178
- Pike13::Desk::Booking.create(
179
- event_occurrence_id: 789,
180
- person_id: 123
181
- )
182
-
183
- # Update booking
181
+ Pike13::Desk::Booking.create(event_occurrence_id: 789, person_id: 123, idempotency_token: SecureRandom.uuid)
184
182
  Pike13::Desk::Booking.update(456, state: "completed")
185
-
186
- # Delete booking
187
183
  Pike13::Desk::Booking.destroy(456)
188
184
  ```
189
185
 
190
186
  #### Visits
191
187
 
192
188
  ```ruby
193
- # List all visits
194
- Pike13::Desk::Visit.all
195
-
196
- # Find visit
197
- Pike13::Desk::Visit.find(456)
198
-
199
- # Get visit summary for a person
200
- Pike13::Desk::Visit.summary(person_id: 123)
189
+ Pike13::Desk::Visit.all # List all visits
190
+ Pike13::Desk::Visit.find(456) # Find visit
191
+ Pike13::Desk::Visit.summary(person_id: 123) # Get visit summary for a person
201
192
  ```
202
193
 
203
194
  #### Locations, Services, Staff
@@ -221,258 +212,138 @@ Pike13::Desk::StaffMember.me
221
212
  #### Plans & Products
222
213
 
223
214
  ```ruby
224
- # Plans
225
- Pike13::Desk::Plan.all
215
+ Pike13::Desk::Plan.all # Plans
226
216
  Pike13::Desk::Plan.find(200)
227
-
228
- # Plan Products
229
- Pike13::Desk::PlanProduct.all
217
+ Pike13::Desk::PlanProduct.all # Plan Products
230
218
  Pike13::Desk::PlanProduct.find(300)
231
-
232
- # Pack Products
233
- Pike13::Desk::PackProduct.all
219
+ Pike13::Desk::PackProduct.all # Pack Products
234
220
  Pike13::Desk::PackProduct.find(400)
235
-
236
- # Packs (find only)
237
- Pike13::Desk::Pack.find(500)
238
-
239
- # Punches (find only)
240
- Pike13::Desk::Punch.find(600)
221
+ Pike13::Desk::Pack.find(500) # Packs (find only)
222
+ Pike13::Desk::Punch.find(600) # Punches (find only)
241
223
  ```
242
224
 
243
225
  #### Invoices & Payments
244
226
 
245
227
  ```ruby
246
- # Invoices
247
- Pike13::Desk::Invoice.all
228
+ Pike13::Desk::Invoice.all # Invoices
248
229
  Pike13::Desk::Invoice.find(700)
249
-
250
- # Payments
251
- Pike13::Desk::Payment.find(800)
230
+ Pike13::Desk::Payment.find(800) # Payments
252
231
  Pike13::Desk::Payment.configuration
253
232
  Pike13::Desk::Payment.void(payment_id: 800, invoice_item_ids_to_cancel: [1, 2])
254
-
255
- # Refunds
256
- Pike13::Desk::Refund.find(900)
233
+ Pike13::Desk::Refund.find(900) # Refunds
257
234
  Pike13::Desk::Refund.void(refund_id: 900)
258
235
  ```
259
236
 
260
237
  #### Financial Settings
261
238
 
262
239
  ```ruby
263
- # Revenue Categories
264
- Pike13::Desk::RevenueCategory.all
240
+ Pike13::Desk::RevenueCategory.all # Revenue Categories
265
241
  Pike13::Desk::RevenueCategory.find(10)
266
-
267
- # Sales Taxes
268
- Pike13::Desk::SalesTax.all
242
+ Pike13::Desk::SalesTax.all # Sales Taxes
269
243
  Pike13::Desk::SalesTax.find(20)
270
244
  ```
271
245
 
272
246
  #### Notes
273
247
 
274
248
  ```ruby
275
- # List notes for a person
276
- Pike13::Desk::Note.all(person_id: 123)
277
-
278
- # Find note
279
- Pike13::Desk::Note.find(person_id: 123, id: 1000)
280
-
281
- # Create note
282
- Pike13::Desk::Note.create(
283
- person_id: 123,
284
- attributes: { body: "This is a note" }
285
- )
286
-
287
- # Update note
288
- Pike13::Desk::Note.update(
289
- person_id: 123,
290
- id: 1000,
291
- attributes: { body: "Updated note" }
292
- )
293
-
294
- # Delete note
249
+ Pike13::Desk::Note.all(person_id: 123) # List notes for a person
250
+ Pike13::Desk::Note.find(person_id: 123, id: 1000) # Find note
251
+ Pike13::Desk::Note.create(person_id: 123, attributes: { note: "This is a note", subject: "Note Subject" })
252
+ Pike13::Desk::Note.update(person_id: 123, id: 1000, attributes: { note: "Updated note" })
295
253
  Pike13::Desk::Note.destroy(person_id: 123, id: 1000)
296
254
  ```
297
255
 
298
256
  #### Make-Ups
299
257
 
300
258
  ```ruby
301
- # Find make-up
302
- Pike13::Desk::MakeUp.find(1100)
303
-
304
- # List make-up reasons
305
- Pike13::Desk::MakeUp.reasons
306
-
307
- # Generate make-up credit
308
- Pike13::Desk::MakeUp.generate(
309
- visit_id: 456,
310
- make_up_reason_id: 5,
311
- free_form_reason: "Client was sick"
312
- )
259
+ Pike13::Desk::MakeUp.find(1100) # Find make-up
260
+ Pike13::Desk::MakeUp.reasons # List make-up reasons
261
+ Pike13::Desk::MakeUp.generate(visit_id: 456, make_up_reason_id: 5, free_form_reason: "Client was sick")
313
262
  ```
314
263
 
315
264
  #### Waitlist
316
265
 
317
266
  ```ruby
318
- # List waitlist entries
319
- Pike13::Desk::WaitlistEntry.all
320
-
321
- # Find waitlist entry
322
- Pike13::Desk::WaitlistEntry.find(1200)
267
+ Pike13::Desk::WaitlistEntry.all # List waitlist entries
268
+ Pike13::Desk::WaitlistEntry.find(1200) # Find waitlist entry
323
269
  ```
324
270
 
325
271
  #### Custom Fields
326
272
 
327
273
  ```ruby
328
- # List custom fields
329
- Pike13::Desk::CustomField.all
330
-
331
- # Find custom field
332
- Pike13::Desk::CustomField.find(30)
274
+ Pike13::Desk::CustomField.all # List custom fields
275
+ Pike13::Desk::CustomField.find(30) # Find custom field
333
276
  ```
334
277
 
335
278
  #### Person-Related Resources
336
279
 
337
280
  ```ruby
338
- # List person's visits
339
- Pike13::Desk::PersonVisit.all(person_id: 123)
340
-
341
- # List person's plans
342
- Pike13::Desk::PersonPlan.all(person_id: 123)
343
-
344
- # List person's waitlist entries
345
- Pike13::Desk::PersonWaitlistEntry.all(person_id: 123)
346
-
347
- # List person's waivers
348
- Pike13::Desk::PersonWaiver.all(person_id: 123)
349
-
350
- # List person's forms of payment
351
- Pike13::Desk::FormOfPayment.all(person_id: 123)
352
-
353
- # Find form of payment
354
- Pike13::Desk::FormOfPayment.find(person_id: 123, id: 456)
355
-
356
- # Create form of payment
357
- Pike13::Desk::FormOfPayment.create(
358
- person_id: 123,
359
- attributes: { token: "tok_xxx" }
360
- )
361
-
362
- # Update form of payment
363
- Pike13::Desk::FormOfPayment.update(
364
- person_id: 123,
365
- id: 456,
366
- attributes: { is_default: true }
367
- )
368
-
369
- # Delete form of payment
281
+ Pike13::Desk::PersonVisit.all(person_id: 123) # List person's visits
282
+ Pike13::Desk::PersonPlan.all(person_id: 123) # List person's plans
283
+ Pike13::Desk::PersonWaitlistEntry.all(person_id: 123) # List person's waitlist entries
284
+ Pike13::Desk::PersonWaiver.all(person_id: 123) # List person's waivers
285
+ Pike13::Desk::FormOfPayment.all(person_id: 123) # List person's forms of payment
286
+ Pike13::Desk::FormOfPayment.find(person_id: 123, id: 456) # Find form of payment
287
+ Pike13::Desk::FormOfPayment.create(person_id: 123, attributes: { type: "creditcard", token: "tok_xxx" })
288
+ Pike13::Desk::FormOfPayment.update(person_id: 123, id: 456, attributes: { is_default: true })
370
289
  Pike13::Desk::FormOfPayment.destroy(person_id: 123, id: 456)
371
290
  ```
372
291
 
373
- ### Front Resources (Client Interface)
292
+ ### Front Resources
374
293
 
375
294
  Client-facing interface with limited read-only access.
376
295
 
377
296
  #### Business & Branding
378
297
 
379
298
  ```ruby
380
- # Get business info
381
- Pike13::Front::Business.find
382
-
383
- # Get branding
384
- Pike13::Front::Branding.find
299
+ Pike13::Front::Business.find # Get business info
300
+ Pike13::Front::Branding.find # Get branding
385
301
  ```
386
302
 
387
303
  #### People
388
304
 
389
305
  ```ruby
390
- # Get authenticated client user (only)
391
- Pike13::Front::Person.me
306
+ Pike13::Front::Person.me # Get authenticated client user (only)
392
307
  ```
393
308
 
394
309
  #### Events & Event Occurrences
395
310
 
396
311
  ```ruby
397
- # List events
398
- Pike13::Front::Event.all
399
-
400
- # Find event
401
- Pike13::Front::Event.find(100)
402
-
403
- # List event occurrences
312
+ Pike13::Front::Event.all # List events
313
+ Pike13::Front::Event.find(100) # Find event
404
314
  Pike13::Front::EventOccurrence.all(from: "2025-01-01", to: "2025-01-31")
405
-
406
- # Find occurrence
407
- Pike13::Front::EventOccurrence.find(789)
408
-
409
- # Get occurrence summary
410
- Pike13::Front::EventOccurrence.summary
411
-
412
- # Check enrollment eligibility
315
+ Pike13::Front::EventOccurrence.find(789) # Find occurrence
316
+ Pike13::Front::EventOccurrence.summary # Get occurrence summary
413
317
  Pike13::Front::EventOccurrence.enrollment_eligibilities(id: 789)
414
-
415
- # List event occurrence notes
416
318
  Pike13::Front::EventOccurrenceNote.all(event_occurrence_id: 789)
417
-
418
- # Find event occurrence note
419
319
  Pike13::Front::EventOccurrenceNote.find(event_occurrence_id: 789, id: 1)
420
-
421
- # List waitlist eligibilities for an event occurrence
422
320
  Pike13::Front::EventOccurrenceWaitlistEligibility.all(event_occurrence_id: 789)
423
321
  ```
424
322
 
425
323
  #### Appointments
426
324
 
427
325
  ```ruby
428
- # Find available slots
429
- Pike13::Front::Appointment.find_available_slots(
430
- service_id: 100,
431
- date: "2025-01-15",
432
- location_ids: [1, 2],
433
- staff_member_ids: [3, 4]
434
- )
435
-
436
- # Get availability summary
437
- Pike13::Front::Appointment.available_slots_summary(
438
- service_id: 100,
439
- from: "2025-01-01",
440
- to: "2025-01-31",
441
- location_ids: [1, 2],
442
- staff_member_ids: [3, 4]
443
- )
326
+ Pike13::Front::Appointment.find_available_slots(service_id: 100, date: "2025-01-15", location_ids: [1, 2], staff_member_ids: [3, 4])
327
+ Pike13::Front::Appointment.available_slots_summary(service_id: 100, from: "2025-01-01", to: "2025-01-31", location_ids: [1, 2], staff_member_ids: [3, 4])
444
328
  ```
445
329
 
446
330
  #### Bookings
447
331
 
332
+ **Note:** Creating bookings requires an `idempotency_token` parameter to prevent duplicate bookings.
333
+
448
334
  ```ruby
449
- # Find booking
450
335
  Pike13::Front::Booking.find(123)
451
-
452
- # Find lease for booking
453
336
  Pike13::Front::Booking.find_lease(booking_id: 123, id: 456)
454
-
455
- # Create booking
456
- Pike13::Front::Booking.create(
457
- event_occurrence_id: 789,
458
- person_id: 123
459
- )
460
-
461
- # Update booking
337
+ Pike13::Front::Booking.create(event_occurrence_id: 789, person_id: 123, idempotency_token: SecureRandom.uuid)
462
338
  Pike13::Front::Booking.update(456, state: "completed")
463
-
464
- # Delete booking
465
339
  Pike13::Front::Booking.destroy(456)
466
340
  ```
467
341
 
468
342
  #### Visits
469
343
 
470
344
  ```ruby
471
- # List visits
472
- Pike13::Front::Visit.all
473
-
474
- # Find visit
475
- Pike13::Front::Visit.find(456)
345
+ Pike13::Front::Visit.all # List visits
346
+ Pike13::Front::Visit.find(456) # Find visit
476
347
  ```
477
348
 
478
349
  #### Locations, Services, Staff
@@ -495,16 +366,11 @@ Pike13::Front::StaffMember.find(5)
495
366
  #### Plans & Products
496
367
 
497
368
  ```ruby
498
- # Plans
499
- Pike13::Front::Plan.all
369
+ Pike13::Front::Plan.all # Plans
500
370
  Pike13::Front::Plan.find(200)
501
-
502
- # Plan Products
503
- Pike13::Front::PlanProduct.all
371
+ Pike13::Front::PlanProduct.all # Plan Products
504
372
  Pike13::Front::PlanProduct.find(300)
505
-
506
- # Plan Terms
507
- Pike13::Front::PlanTerms.all(plan_id: 200)
373
+ Pike13::Front::PlanTerms.all(plan_id: 200) # Plan Terms
508
374
  Pike13::Front::PlanTerms.find(plan_id: 200, plan_terms_id: 1)
509
375
  Pike13::Front::PlanTerms.complete(plan_id: 200, plan_terms_id: 1)
510
376
  ```
@@ -512,75 +378,1114 @@ Pike13::Front::PlanTerms.complete(plan_id: 200, plan_terms_id: 1)
512
378
  #### Invoices & Payments
513
379
 
514
380
  ```ruby
515
- # Invoices (find only)
516
- Pike13::Front::Invoice.find(700)
517
-
518
- # Payments
519
- Pike13::Front::Payment.find(800)
381
+ Pike13::Front::Invoice.find(700) # Invoices (find only)
382
+ Pike13::Front::Payment.find(800) # Payments
520
383
  Pike13::Front::Payment.configuration
521
384
  ```
522
385
 
523
386
  #### Notes
524
387
 
525
388
  ```ruby
526
- # List notes for a person
527
- Pike13::Front::Note.all(person_id: 123)
528
-
529
- # Find note
530
- Pike13::Front::Note.find(person_id: 123, id: 1000)
389
+ Pike13::Front::Note.all(person_id: 123) # List notes for a person
390
+ Pike13::Front::Note.find(person_id: 123, id: 1000) # Find note
531
391
  ```
532
392
 
533
393
  #### Waitlist
534
394
 
535
395
  ```ruby
536
- # List waitlist entries
537
- Pike13::Front::WaitlistEntry.all
538
-
539
- # Find waitlist entry
540
- Pike13::Front::WaitlistEntry.find(1200)
396
+ Pike13::Front::WaitlistEntry.all # List waitlist entries
397
+ Pike13::Front::WaitlistEntry.find(1200) # Find waitlist entry
541
398
  ```
542
399
 
543
400
  #### Person-Related Resources
544
401
 
545
402
  ```ruby
546
- # List person's visits
547
- Pike13::Front::PersonVisit.all(person_id: 123)
403
+ Pike13::Front::PersonVisit.all(person_id: 123) # List person's visits
404
+ Pike13::Front::PersonPlan.all(person_id: 123) # List person's plans
405
+ Pike13::Front::PersonWaitlistEntry.all(person_id: 123) # List person's waitlist entries
406
+ Pike13::Front::PersonWaiver.all(person_id: 123) # List person's waivers
407
+ Pike13::Front::FormOfPayment.all(person_id: 123) # List person's forms of payment
408
+ Pike13::Front::FormOfPayment.find(person_id: 123, id: 456) # Find form of payment
409
+ Pike13::Front::FormOfPayment.find_me(id: 456) # Find form of payment for authenticated user
410
+ Pike13::Front::FormOfPayment.create(person_id: 123, attributes: { type: "creditcard", token: "tok_xxx" })
411
+ Pike13::Front::FormOfPayment.update(person_id: 123, id: 456, attributes: { is_default: true })
412
+ Pike13::Front::FormOfPayment.destroy(person_id: 123, id: 456)
413
+ ```
414
+
415
+ ### Reporting Resources
548
416
 
549
- # List person's plans
550
- Pike13::Front::PersonPlan.all(person_id: 123)
417
+ Advanced query-based analytics for business insights. The Reporting API uses a different architecture than the Core API - it's designed for complex analytical queries with filtering, grouping, sorting, and aggregation capabilities.
551
418
 
552
- # List person's waitlist entries
553
- Pike13::Front::PersonWaitlistEntry.all(person_id: 123)
419
+ **Note:** The v3 Reporting API conforms to [JSON API 1.0](https://jsonapi.org/format/1.0/) specification and uses `application/vnd.api+json` content type.
554
420
 
555
- # List person's waivers
556
- Pike13::Front::PersonWaiver.all(person_id: 123)
421
+ **Available Reporting Endpoints:**
422
+ - **Monthly Business Metrics** - Monthly transaction amounts, members, and enrollments
423
+ - **Clients** - Client demographics, tenure, visits, and engagement
424
+ - **Transactions** - Payment transactions, methods, and processing details
425
+ - **Invoices** - Invoice amounts, states, and payment tracking
426
+ - **Enrollments** - Visit/enrollment details and attendance patterns
427
+ - **Person Plans** - Active plans, memberships, and usage tracking
428
+ - **Event Occurrences** - Scheduled events, capacity, and attendance
429
+ - **Event Occurrence Staff Members** - Staff assignments and event workload
430
+ - **Invoice Items** - Line-item details and revenue breakdown
431
+ - **Invoice Item Transactions** - Transaction-level payment and refund tracking
432
+ - **Pays** - Staff compensation, pay rates, and service hours
433
+ - **Staff Members** - Staff roster, tenure, roles, and event assignments
557
434
 
558
- # List person's forms of payment
559
- Pike13::Front::FormOfPayment.all(person_id: 123)
435
+ All reporting endpoints support:
436
+ - **Filtering** - Query specific subsets of data
437
+ - **Grouping** - Aggregate data by dimensions
438
+ - **Sorting** - Order results by any field
439
+ - **Pagination** - Handle large result sets efficiently
560
440
 
561
- # Find form of payment
562
- Pike13::Front::FormOfPayment.find(person_id: 123, id: 456)
441
+ #### Monthly Business Metrics
563
442
 
564
- # Find form of payment for authenticated user
565
- Pike13::Front::FormOfPayment.find_me(id: 456)
443
+ Summary of monthly transaction amounts, members, and enrollments over the lifetime of your business.
566
444
 
567
- # Create form of payment
568
- Pike13::Front::FormOfPayment.create(
569
- person_id: 123,
570
- attributes: { token: "tok_xxx" }
445
+ ```ruby
446
+ # Basic query - get specific fields for all months
447
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
448
+ fields: ['month_start_date', 'net_paid_amount', 'new_client_count', 'member_count']
571
449
  )
572
450
 
573
- # Update form of payment
574
- Pike13::Front::FormOfPayment.update(
575
- person_id: 123,
576
- id: 456,
577
- attributes: { is_default: true }
451
+ # Query with date range filter
452
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
453
+ fields: ['month_start_date', 'net_paid_amount', 'completed_enrollment_count'],
454
+ filter: ['btw', 'month_start_date', '2024-01-01', '2024-12-31']
578
455
  )
579
456
 
580
- # Delete form of payment
581
- Pike13::Front::FormOfPayment.destroy(person_id: 123, id: 456)
457
+ # Query with sorting (descending by date)
458
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
459
+ fields: ['month_start_date', 'net_paid_revenue_amount', 'first_visit_count'],
460
+ sort: ['month_start_date-']
461
+ )
462
+
463
+ # Query with grouping (summary fields required)
464
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
465
+ fields: ['total_net_paid_amount', 'total_new_client_count', 'avg_member_count'],
466
+ group: 'year_start_date'
467
+ )
468
+
469
+ # Query with pagination
470
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
471
+ fields: ['month_start_date', 'net_paid_amount'],
472
+ page: { limit: 50 }
473
+ )
474
+
475
+ # Complex query with multiple filters
476
+ Pike13::Reporting::MonthlyBusinessMetrics.query(
477
+ fields: [
478
+ 'month_start_date',
479
+ 'net_paid_revenue_amount',
480
+ 'new_client_count',
481
+ 'member_count',
482
+ 'completed_enrollment_count'
483
+ ],
484
+ filter: [
485
+ 'and',
486
+ [
487
+ ['btw', 'month_start_date', '2024-01-01', '2024-12-31'],
488
+ ['gt', 'net_paid_amount', 0]
489
+ ]
490
+ ],
491
+ sort: ['net_paid_amount-'],
492
+ total_count: true
493
+ )
494
+ ```
495
+
496
+ **Available Detail Fields** (when not grouping):
497
+ - Revenue: `net_paid_amount`, `net_paid_revenue_amount`, `payments_amount`, `refunds_amount`
498
+ - Clients: `new_client_count`, `member_count`, `client_w_plan_count`, `first_visit_count`
499
+ - Enrollments: `enrollment_count`, `completed_enrollment_count`, `completed_enrollment_per_client`
500
+ - Events: `event_occurrence_count`, `class_count`, `appointment_count`, `course_count`
501
+ - Plans: `pack_count`, `membership_count`, `prepaid_count`, `plan_start_count`, `plan_end_count`
502
+ - See `Pike13::Reporting::MonthlyBusinessMetrics::DETAIL_FIELDS` for the full list
503
+
504
+ **Available Summary Fields** (when grouping):
505
+ - `total_net_paid_amount`, `total_net_paid_revenue_amount`, `total_payments_amount`
506
+ - `total_new_client_count`, `avg_member_count`, `avg_client_w_plan_count`
507
+ - `total_enrollment_count`, `total_completed_enrollment_count`, `total_first_visit_count`
508
+ - See `Pike13::Reporting::MonthlyBusinessMetrics::SUMMARY_FIELDS` for the full list
509
+
510
+ **Available Groupings**:
511
+ - `business_id`, `business_name`, `business_subdomain`
512
+ - `currency_code`
513
+ - `quarter_start_date`, `year_start_date`
514
+
515
+ #### Clients
516
+
517
+ All client data — from tenure and unpaid bills to birthdays and passes held.
518
+
519
+ ```ruby
520
+ # Basic query - get client contact information
521
+ Pike13::Reporting::Clients.query(
522
+ fields: ['person_id', 'full_name', 'email', 'phone', 'client_since_date']
523
+ )
524
+
525
+ # Query for clients with memberships
526
+ Pike13::Reporting::Clients.query(
527
+ fields: ['full_name', 'email', 'has_membership', 'tenure', 'completed_visits'],
528
+ filter: ['eq', 'has_membership', true]
529
+ )
530
+
531
+ # Query for active clients with unpaid invoices
532
+ Pike13::Reporting::Clients.query(
533
+ fields: ['full_name', 'email', 'last_invoice_amount', 'last_invoice_date'],
534
+ filter: [
535
+ 'and',
536
+ [
537
+ ['eq', 'person_state', 'active'],
538
+ ['eq', 'last_invoice_unpaid', true]
539
+ ]
540
+ ]
541
+ )
542
+
543
+ # Query for clients by tenure group
544
+ Pike13::Reporting::Clients.query(
545
+ fields: ['full_name', 'email', 'tenure', 'tenure_group', 'completed_visits'],
546
+ filter: ['eq', 'tenure_group', '5_over_three_years'],
547
+ sort: ['completed_visits-']
548
+ )
549
+
550
+ # Group clients by tenure and count
551
+ Pike13::Reporting::Clients.query(
552
+ fields: ['person_count', 'has_membership_count', 'total_completed_visits'],
553
+ group: 'tenure_group'
554
+ )
555
+
556
+ # Search for clients by name
557
+ Pike13::Reporting::Clients.query(
558
+ fields: ['person_id', 'full_name', 'email', 'phone'],
559
+ filter: ['contains', 'full_name', 'Smith']
560
+ )
582
561
  ```
583
562
 
563
+ **Available Detail Fields** (when not grouping):
564
+ - Identity: `person_id`, `full_name`, `first_name`, `last_name`, `email`, `phone`
565
+ - Address: `street_address`, `street_address2`, `city`, `state_code`, `postal_code`, `country_code`
566
+ - Membership: `has_membership`, `current_plans`, `has_payment_on_file`, `has_plan_on_hold`
567
+ - Activity: `completed_visits`, `future_visits`, `unpaid_visits`, `last_visit_date`, `first_visit_date`
568
+ - Financial: `net_paid_amount`, `revenue_amount`, `account_credit_amount`, `last_invoice_amount`
569
+ - Tenure: `client_since_date`, `tenure`, `tenure_group`, `days_since_last_visit`
570
+ - Status: `person_state`, `is_schedulable`, `also_staff`, `has_signed_waiver`
571
+ - See `Pike13::Reporting::Clients::DETAIL_FIELDS` for the full list
572
+
573
+ **Available Summary Fields** (when grouping):
574
+ - `person_count`, `has_membership_count`, `has_payment_on_file_count`
575
+ - `total_completed_visits`, `total_future_visits`, `total_unpaid_visits`
576
+ - `total_net_paid_amount`, `total_revenue_amount`, `total_account_credit_amount`
577
+ - See `Pike13::Reporting::Clients::SUMMARY_FIELDS` for the full list
578
+
579
+ **Available Groupings**:
580
+ - Client attributes: `tenure_group`, `person_state`, `source_name`, `age`
581
+ - Location: `business_id`, `business_name`, `home_location_name`
582
+ - Dates: `client_since_date`, `client_since_month_start_date`, `client_since_quarter_start_date`, `client_since_year_start_date`
583
+ - Boolean flags: `has_membership`, `has_payment_on_file`, `is_schedulable`, `also_staff`
584
+
585
+ #### Transactions
586
+
587
+ Data about the money moving through your business.
588
+
589
+ ```ruby
590
+ # Basic query - get recent transactions
591
+ Pike13::Reporting::Transactions.query(
592
+ fields: ['transaction_id', 'transaction_date', 'net_paid_amount', 'payment_method', 'invoice_payer_name']
593
+ )
594
+
595
+ # Query transactions by date range
596
+ Pike13::Reporting::Transactions.query(
597
+ fields: ['transaction_date', 'net_paid_amount', 'invoice_payer_name', 'payment_method'],
598
+ filter: ['btw', 'transaction_date', '2024-01-01', '2024-12-31'],
599
+ sort: ['transaction_date-']
600
+ )
601
+
602
+ # Query by payment method
603
+ Pike13::Reporting::Transactions.query(
604
+ fields: ['transaction_date', 'net_paid_amount', 'invoice_payer_name'],
605
+ filter: ['eq', 'payment_method', 'creditcard']
606
+ )
607
+
608
+ # Query failed transactions
609
+ Pike13::Reporting::Transactions.query(
610
+ fields: ['transaction_date', 'transaction_amount', 'error_message', 'invoice_payer_name'],
611
+ filter: ['eq', 'transaction_state', 'failed']
612
+ )
613
+
614
+ # Group by payment method
615
+ Pike13::Reporting::Transactions.query(
616
+ fields: ['total_net_paid_amount', 'total_payments_amount', 'transaction_count'],
617
+ group: 'payment_method'
618
+ )
619
+
620
+ # Group by month to see revenue trends
621
+ Pike13::Reporting::Transactions.query(
622
+ fields: ['total_net_paid_amount', 'total_net_paid_revenue_amount', 'transaction_count'],
623
+ group: 'transaction_month_start_date',
624
+ sort: ['transaction_month_start_date']
625
+ )
626
+
627
+ # Detailed breakdown by card type
628
+ Pike13::Reporting::Transactions.query(
629
+ fields: [
630
+ 'total_net_visa_paid_amount',
631
+ 'total_net_mastercard_paid_amount',
632
+ 'total_net_american_express_paid_amount',
633
+ 'total_net_discover_paid_amount'
634
+ ],
635
+ group: 'transaction_month_start_date'
636
+ )
637
+ ```
638
+
639
+ **Available Detail Fields** (when not grouping):
640
+ - Transaction: `transaction_id`, `transaction_date`, `transaction_at`, `transaction_state`, `transaction_type`
641
+ - Amounts: `net_paid_amount`, `net_paid_revenue_amount`, `net_paid_tax_amount`, `payments_amount`, `refunds_amount`
642
+ - Payment: `payment_method`, `payment_method_detail`, `credit_card_name`, `processing_method`, `processor_transaction_id`
643
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_due_date`, `invoice_autobill`
644
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_email`, `invoice_payer_phone`
645
+ - Other: `created_by_name`, `commission_recipient_name`, `sale_location_name`, `error_message`
646
+ - See `Pike13::Reporting::Transactions::DETAIL_FIELDS` for the full list
647
+
648
+ **Available Summary Fields** (when grouping):
649
+ - Totals: `total_net_paid_amount`, `total_net_paid_revenue_amount`, `total_net_paid_tax_amount`
650
+ - Counts: `transaction_count`, `invoice_count`, `failed_count`, `settled_count`
651
+ - By payment method: `total_net_cash_paid_amount`, `total_net_check_paid_amount`, `total_net_credit_paid_amount`
652
+ - By card type: `total_net_visa_paid_amount`, `total_net_mastercard_paid_amount`, `total_net_american_express_paid_amount`, `total_net_discover_paid_amount`
653
+ - By processor: `total_net_amex_processing_paid_amount`, `total_net_global_pay_processing_paid_amount`
654
+ - See `Pike13::Reporting::Transactions::SUMMARY_FIELDS` for the full list
655
+
656
+ **Available Groupings**:
657
+ - Payment: `payment_method`, `credit_card_name`, `processing_method`, `external_payment_name`
658
+ - Dates: `transaction_date`, `transaction_month_start_date`, `transaction_quarter_start_date`, `transaction_year_start_date`
659
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_payer_id`, `invoice_payer_name`
660
+ - States: `transaction_state`, `transaction_type`, `transaction_autopay`
661
+ - Location: `business_id`, `business_name`, `sale_location_name`
662
+
663
+ #### Invoices
664
+
665
+ Details of invoices, their status, revenue, and payment information.
666
+
667
+ ```ruby
668
+ # Basic query - get all invoices
669
+ Pike13::Reporting::Invoices.query(
670
+ fields: ['invoice_id', 'invoice_number', 'expected_amount', 'outstanding_amount', 'invoice_state']
671
+ )
672
+
673
+ # Query unpaid invoices
674
+ Pike13::Reporting::Invoices.query(
675
+ fields: ['invoice_number', 'invoice_payer_name', 'outstanding_amount', 'invoice_due_date'],
676
+ filter: ['gt', 'outstanding_amount', 0],
677
+ sort: ['invoice_due_date']
678
+ )
679
+
680
+ # Query overdue invoices
681
+ Pike13::Reporting::Invoices.query(
682
+ fields: ['invoice_number', 'invoice_payer_name', 'outstanding_amount', 'days_since_invoice_due'],
683
+ filter: [
684
+ 'and',
685
+ [
686
+ ['eq', 'invoice_state', 'open'],
687
+ ['gt', 'days_since_invoice_due', 0]
688
+ ]
689
+ ]
690
+ )
691
+
692
+ # Query by date range
693
+ Pike13::Reporting::Invoices.query(
694
+ fields: ['invoice_number', 'expected_amount', 'net_paid_amount', 'invoice_payer_name'],
695
+ filter: ['btw', 'issued_date', '2024-01-01', '2024-12-31']
696
+ )
697
+
698
+ # Group by invoice state
699
+ Pike13::Reporting::Invoices.query(
700
+ fields: ['invoice_count', 'total_expected_amount', 'total_outstanding_amount'],
701
+ group: 'invoice_state'
702
+ )
703
+
704
+ # Monthly revenue summary
705
+ Pike13::Reporting::Invoices.query(
706
+ fields: ['total_expected_amount', 'total_net_paid_amount', 'total_outstanding_amount', 'invoice_count'],
707
+ group: 'issued_month_start_date',
708
+ sort: ['issued_month_start_date']
709
+ )
710
+
711
+ # Query with discounts and coupons
712
+ Pike13::Reporting::Invoices.query(
713
+ fields: [
714
+ 'invoice_number',
715
+ 'gross_amount',
716
+ 'discounts_amount',
717
+ 'coupons_amount',
718
+ 'expected_amount'
719
+ ],
720
+ filter: ['gt', 'discounts_amount', 0]
721
+ )
722
+ ```
723
+
724
+ **Available Detail Fields** (when not grouping):
725
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_due_date`, `invoice_autobill`
726
+ - Amounts: `gross_amount`, `expected_amount`, `net_paid_amount`, `outstanding_amount`
727
+ - Revenue/Tax: `expected_revenue_amount`, `expected_tax_amount`, `net_paid_revenue_amount`, `net_paid_tax_amount`
728
+ - Adjustments: `discounts_amount`, `coupons_amount`, `adjustments_amount`
729
+ - Payments: `payments_amount`, `refunds_amount`, `failed_transactions`, `refunded_transactions`, `voided_transactions`
730
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_email`, `invoice_payer_phone`
731
+ - Dates: `issued_date`, `issued_at`, `closed_date`, `closed_at`, `days_since_invoice_due`
732
+ - Other: `created_by_name`, `created_by_client`, `commission_recipient_name`, `sale_location_name`
733
+ - See `Pike13::Reporting::Invoices::DETAIL_FIELDS` for the full list
734
+
735
+ **Available Summary Fields** (when grouping):
736
+ - Counts: `invoice_count`, `created_by_client_count`, `invoice_autobill_count`
737
+ - Totals: `total_expected_amount`, `total_net_paid_amount`, `total_outstanding_amount`
738
+ - Revenue/Tax: `total_expected_revenue_amount`, `total_net_paid_revenue_amount`, `total_outstanding_revenue_amount`
739
+ - Adjustments: `total_discounts_amount`, `total_coupons_amount`, `total_adjustments_amount`
740
+ - See `Pike13::Reporting::Invoices::SUMMARY_FIELDS` for the full list
741
+
742
+ **Available Groupings**:
743
+ - State: `invoice_state`, `purchase_request_state`, `created_by_client`, `invoice_autobill`
744
+ - Dates: `issued_date`, `issued_month_start_date`, `closed_date`, `closed_month_start_date`, `invoice_due_date`
745
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_home_location`
746
+ - Business: `business_id`, `business_name`, `sale_location_name`, `commission_recipient_name`
747
+
748
+ #### Enrollments
749
+
750
+ Data about visit and waitlist history, behavior, and trends.
751
+
752
+ ```ruby
753
+ # Basic query - get visit details
754
+ Pike13::Reporting::Enrollments.query(
755
+ fields: ['visit_id', 'full_name', 'service_name', 'state', 'service_date']
756
+ )
757
+
758
+ # Query completed visits
759
+ Pike13::Reporting::Enrollments.query(
760
+ fields: ['full_name', 'service_name', 'service_date', 'estimated_amount', 'instructor_names'],
761
+ filter: ['eq', 'state', 'completed'],
762
+ sort: ['service_date-']
763
+ )
764
+
765
+ # Query by date range
766
+ Pike13::Reporting::Enrollments.query(
767
+ fields: ['full_name', 'service_name', 'service_date', 'state'],
768
+ filter: ['btw', 'service_date', '2024-01-01', '2024-12-31']
769
+ )
770
+
771
+ # Query first-time visitors
772
+ Pike13::Reporting::Enrollments.query(
773
+ fields: ['full_name', 'email', 'service_name', 'service_date'],
774
+ filter: ['eq', 'first_visit', true]
775
+ )
776
+
777
+ # Query unpaid visits
778
+ Pike13::Reporting::Enrollments.query(
779
+ fields: ['full_name', 'service_name', 'service_date', 'available_plans'],
780
+ filter: ['eq', 'is_paid', false]
781
+ )
782
+
783
+ # Group by service to analyze attendance
784
+ Pike13::Reporting::Enrollments.query(
785
+ fields: ['completed_enrollment_count', 'noshowed_enrollment_count', 'total_visits_amount'],
786
+ group: 'service_name'
787
+ )
788
+
789
+ # Group by day of week
790
+ Pike13::Reporting::Enrollments.query(
791
+ fields: [
792
+ 'enrollment_count',
793
+ 'weekday_0_enrollment_count',
794
+ 'weekday_1_enrollment_count',
795
+ 'weekday_2_enrollment_count',
796
+ 'weekday_3_enrollment_count',
797
+ 'weekday_4_enrollment_count',
798
+ 'weekday_5_enrollment_count',
799
+ 'weekday_6_enrollment_count'
800
+ ],
801
+ group: 'service_month_start_date'
802
+ )
803
+
804
+ # Analyze client booking patterns
805
+ Pike13::Reporting::Enrollments.query(
806
+ fields: ['enrollment_count', 'client_booked_count'],
807
+ group: 'service_type'
808
+ )
809
+ ```
810
+
811
+ **Available Detail Fields** (when not grouping):
812
+ - Visit: `visit_id`, `state`, `service_date`, `service_time`, `start_at`, `end_at`
813
+ - Person: `person_id`, `full_name`, `email`, `phone`, `birthdate`, `home_location_name`
814
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`
815
+ - Event: `event_id`, `event_name`, `event_occurrence_id`, `instructor_names`
816
+ - Payment: `is_paid`, `estimated_amount`, `paid_with`, `paid_with_type`, `plan_id`, `punch_id`
817
+ - Status: `first_visit`, `client_booked`, `bulk_enrolled`, `is_waitlist`, `make_up_issued`
818
+ - Timing: `registered_at`, `completed_at`, `cancelled_at`, `noshow_at`, `waitlisted_at`, `cancelled_to_start`
819
+ - Duration: `duration_in_hours`, `duration_in_minutes`
820
+ - See `Pike13::Reporting::Enrollments::DETAIL_FIELDS` for the full list
821
+
822
+ **Available Summary Fields** (when grouping):
823
+ - Counts: `enrollment_count`, `visit_count`, `person_count`, `event_count`, `service_count`
824
+ - By state: `completed_enrollment_count`, `registered_enrollment_count`, `noshowed_enrollment_count`, `late_canceled_enrollment_count`
825
+ - Waitlist: `is_waitlist_count`, `waiting_enrollment_count`, `expired_enrollment_count`, `removed_enrollment_count`
826
+ - Payment: `is_paid_count`, `unpaid_visit_count`, `unpaid_visit_percent`, `total_visits_amount`, `avg_per_visit_amount`
827
+ - By day: `weekday_0_enrollment_count` through `weekday_6_enrollment_count` (Sunday through Saturday)
828
+ - Other: `first_visit_count`, `client_booked_count`, `consider_member_count`, `is_rollover_count`
829
+ - See `Pike13::Reporting::Enrollments::SUMMARY_FIELDS` for the full list
830
+
831
+ **Available Groupings**:
832
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`
833
+ - Dates: `service_date`, `service_month_start_date`, `service_quarter_start_date`, `service_year_start_date`, `service_day`, `service_time`
834
+ - Event: `event_id`, `event_name`, `event_occurrence_id`, `instructor_names`
835
+ - Person: `person_id`, `full_name`, `home_location_name`, `primary_staff_name`
836
+ - Payment: `paid_with`, `paid_with_type`, `plan_id`, `punch_id`, `is_paid`
837
+ - Status: `state`, `first_visit`, `client_booked`, `is_waitlist`, `consider_member`
838
+ - Business: `business_id`, `business_name`, `business_subdomain`
839
+
840
+ #### Event Occurrences
841
+
842
+ Data about scheduled instances of services (e.g., "Group Workout from 9am-10am on 2024/09/01").
843
+
844
+ ```ruby
845
+ # Basic query - get event occurrence details
846
+ Pike13::Reporting::EventOccurrences.query(
847
+ fields: ['event_occurrence_id', 'event_name', 'service_date', 'enrollment_count', 'capacity']
848
+ )
849
+
850
+ # Query high-attendance classes
851
+ Pike13::Reporting::EventOccurrences.query(
852
+ fields: ['event_name', 'service_date', 'service_time', 'completed_enrollment_count', 'capacity'],
853
+ filter: ['gt', 'completed_enrollment_count', 15],
854
+ sort: ['completed_enrollment_count-']
855
+ )
856
+
857
+ # Query classes with available spots
858
+ Pike13::Reporting::EventOccurrences.query(
859
+ fields: ['event_name', 'service_date', 'enrollment_count', 'capacity', 'instructor_names'],
860
+ filter: ['lt', 'enrollment_count', 'capacity']
861
+ )
862
+
863
+ # Query by date range and service type
864
+ Pike13::Reporting::EventOccurrences.query(
865
+ fields: ['event_name', 'service_date', 'service_time', 'enrollment_count', 'service_type'],
866
+ filter: [
867
+ 'and',
868
+ [
869
+ ['btw', 'service_date', '2024-01-01', '2024-12-31'],
870
+ ['eq', 'service_type', 'group_class']
871
+ ]
872
+ ]
873
+ )
874
+
875
+ # Track attendance completion
876
+ Pike13::Reporting::EventOccurrences.query(
877
+ fields: ['event_name', 'service_date', 'attendance_completed', 'completed_enrollment_count', 'noshowed_enrollment_count'],
878
+ filter: ['eq', 'attendance_completed', true]
879
+ )
880
+
881
+ # Analyze no-shows and cancellations
882
+ Pike13::Reporting::EventOccurrences.query(
883
+ fields: ['event_name', 'service_date', 'noshowed_enrollment_count', 'late_canceled_enrollment_count', 'enrollment_count']
884
+ )
885
+
886
+ # Group by service name to analyze performance
887
+ Pike13::Reporting::EventOccurrences.query(
888
+ fields: ['total_enrollment_count', 'total_completed_enrollment_count', 'total_noshowed_enrollment_count', 'total_capacity'],
889
+ group: 'service_name'
890
+ )
891
+
892
+ # Group by instructor to track performance
893
+ Pike13::Reporting::EventOccurrences.query(
894
+ fields: ['event_occurrence_count', 'total_enrollment_count', 'total_completed_enrollment_count'],
895
+ group: 'instructor_names'
896
+ )
897
+
898
+ # Monthly class summary
899
+ Pike13::Reporting::EventOccurrences.query(
900
+ fields: ['event_occurrence_count', 'total_enrollment_count', 'total_duration_in_hours'],
901
+ group: 'service_month_start_date'
902
+ )
903
+ ```
904
+
905
+ **Available Detail Fields** (when not grouping):
906
+ - Event Occurrence: `event_occurrence_id`, `event_id`, `event_name`, `service_date`, `service_time`, `start_at`, `end_at`
907
+ - Capacity: `capacity`, `enrollment_count`, `visit_count`, `is_waitlist_count`, `waitlist_to_visit_count`
908
+ - Attendance: `attendance_completed`, `completed_enrollment_count`, `registered_enrollment_count`, `noshowed_enrollment_count`
909
+ - Enrollment states: `late_canceled_enrollment_count`, `expired_enrollment_count`, `removed_enrollment_count`, `reserved_enrollment_count`, `waiting_enrollment_count`
910
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`, `service_state`
911
+ - Instructor: `instructor_names`
912
+ - Payment: `paid_count`, `completed_unpaid_count`
913
+ - Duration: `duration_in_hours`, `duration_in_minutes`
914
+ - See `Pike13::Reporting::EventOccurrences::DETAIL_FIELDS` for the full list
915
+
916
+ **Available Summary Fields** (when grouping):
917
+ - Counts: `event_occurrence_count`, `event_count`, `service_count`, `total_count`
918
+ - Capacity: `total_capacity`, `total_enrollment_count`, `total_visit_count`, `total_is_waitlist_count`
919
+ - Attendance: `attendance_completed_count`, `total_completed_enrollment_count`, `total_registered_enrollment_count`, `total_noshowed_enrollment_count`
920
+ - Enrollment states: `total_late_canceled_enrollment_count`, `total_expired_enrollment_count`, `total_removed_enrollment_count`, `total_reserved_enrollment_count`, `total_waiting_enrollment_count`
921
+ - Payment: `total_paid_count`, `total_completed_unpaid_count`
922
+ - Duration: `total_duration_in_hours`, `total_duration_in_minutes`
923
+ - Other: `total_waitlist_to_visit_count`
924
+ - See `Pike13::Reporting::EventOccurrences::SUMMARY_FIELDS` for the full list
925
+
926
+ **Available Groupings**:
927
+ - Event: `event_id`, `event_name`, `event_occurrence_id`, `instructor_names`
928
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`, `service_state`
929
+ - Dates: `service_date`, `service_day`, `service_time`, `service_month_start_date`, `service_quarter_start_date`, `service_year_start_date`
930
+ - Week groupings: `service_week_mon_start_date`, `service_week_sun_start_date`
931
+ - Status: `attendance_completed`
932
+ - Business: `business_id`, `business_name`, `business_subdomain`
933
+
934
+ #### Event Occurrence Staff Members
935
+
936
+ Details of event occurrences by staff member (instructor, trainer, or organizer). If multiple staff members exist for an event occurrence, a record displays for each.
937
+
938
+ ```ruby
939
+ # Basic query - get event occurrences by staff member
940
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
941
+ fields: ['event_occurrence_id', 'full_name', 'event_name', 'service_date', 'enrollment_count']
942
+ )
943
+
944
+ # Query by specific staff member
945
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
946
+ fields: ['full_name', 'event_name', 'service_date', 'service_time', 'completed_enrollment_count', 'role'],
947
+ filter: ['eq', 'person_id', 12345],
948
+ sort: ['service_date-']
949
+ )
950
+
951
+ # Query with staff contact information
952
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
953
+ fields: ['full_name', 'email', 'phone', 'event_name', 'service_date', 'enrollment_count']
954
+ )
955
+
956
+ # Query by role and date range
957
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
958
+ fields: ['full_name', 'role', 'event_name', 'service_date', 'completed_enrollment_count'],
959
+ filter: [
960
+ 'and',
961
+ [
962
+ ['eq', 'role', 'owner'],
963
+ ['btw', 'service_date', '2024-01-01', '2024-12-31']
964
+ ]
965
+ ]
966
+ )
967
+
968
+ # Track attendance completion by staff
969
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
970
+ fields: ['full_name', 'event_name', 'service_date', 'attendance_completed', 'completed_enrollment_count', 'noshowed_enrollment_count']
971
+ )
972
+
973
+ # Analyze staff workload
974
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
975
+ fields: ['full_name', 'event_name', 'service_date', 'duration_in_hours', 'enrollment_count', 'capacity']
976
+ )
977
+
978
+ # Group by staff member to analyze performance
979
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
980
+ fields: ['event_occurrence_count', 'total_enrollment_count', 'total_completed_enrollment_count', 'total_duration_in_hours'],
981
+ group: 'full_name'
982
+ )
983
+
984
+ # Group by service and staff
985
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
986
+ fields: ['person_count', 'event_occurrence_count', 'total_enrollment_count'],
987
+ group: 'service_name'
988
+ )
989
+
990
+ # Monthly summary by staff role
991
+ Pike13::Reporting::EventOccurrenceStaffMembers.query(
992
+ fields: ['person_count', 'event_occurrence_count', 'total_duration_in_hours'],
993
+ group: 'role'
994
+ )
995
+ ```
996
+
997
+ **Available Detail Fields** (when not grouping):
998
+ - Staff Member: `person_id`, `full_name`, `email`, `phone`, `role`, `home_location_name`
999
+ - Address: `address`, `street_address`, `street_address2`, `city`, `state_code`, `postal_code`, `country_code`
1000
+ - Event Occurrence: `event_occurrence_id`, `event_id`, `event_name`, `service_date`, `service_time`, `start_at`, `end_at`
1001
+ - Capacity: `capacity`, `enrollment_count`, `visit_count`, `is_waitlist_count`, `waitlist_to_visit_count`
1002
+ - Attendance: `attendance_completed`, `completed_enrollment_count`, `registered_enrollment_count`, `noshowed_enrollment_count`
1003
+ - Enrollment states: `late_canceled_enrollment_count`, `expired_enrollment_count`, `removed_enrollment_count`, `reserved_enrollment_count`, `waiting_enrollment_count`
1004
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`, `service_state`
1005
+ - Payment: `paid_count`, `completed_unpaid_count`
1006
+ - Duration: `duration_in_hours`, `duration_in_minutes`
1007
+ - See `Pike13::Reporting::EventOccurrenceStaffMembers::DETAIL_FIELDS` for the full list
1008
+
1009
+ **Available Summary Fields** (when grouping):
1010
+ - Counts: `event_occurrence_count`, `event_count`, `service_count`, `person_count`, `total_count`
1011
+ - Capacity: `total_capacity`, `total_enrollment_count`, `total_visit_count`, `total_is_waitlist_count`
1012
+ - Attendance: `attendance_completed_count`, `total_completed_enrollment_count`, `total_registered_enrollment_count`, `total_noshowed_enrollment_count`
1013
+ - Enrollment states: `total_late_canceled_enrollment_count`, `total_expired_enrollment_count`, `total_removed_enrollment_count`, `total_reserved_enrollment_count`, `total_waiting_enrollment_count`
1014
+ - Payment: `total_paid_count`, `total_completed_unpaid_count`
1015
+ - Duration: `total_duration_in_hours`, `total_duration_in_minutes`
1016
+ - Other: `total_waitlist_to_visit_count`
1017
+ - See `Pike13::Reporting::EventOccurrenceStaffMembers::SUMMARY_FIELDS` for the full list
1018
+
1019
+ **Available Groupings**:
1020
+ - Staff: `person_id`, `full_name`, `role`
1021
+ - Event: `event_id`, `event_name`, `event_occurrence_id`
1022
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_location_name`, `service_state`
1023
+ - Dates: `service_date`, `service_day`, `service_time`, `service_month_start_date`, `service_quarter_start_date`, `service_year_start_date`
1024
+ - Week groupings: `service_week_mon_start_date`, `service_week_sun_start_date`
1025
+ - Status: `attendance_completed`
1026
+ - Business: `business_id`, `business_name`, `business_subdomain`
1027
+
1028
+ #### Invoice Items
1029
+
1030
+ Item-level details of invoices.
1031
+
1032
+ ```ruby
1033
+ # Basic query - get invoice item details
1034
+ Pike13::Reporting::InvoiceItems.query(
1035
+ fields: ['invoice_item_id', 'invoice_number', 'product_name', 'expected_amount', 'invoice_state']
1036
+ )
1037
+
1038
+ # Query by product type
1039
+ Pike13::Reporting::InvoiceItems.query(
1040
+ fields: ['product_name', 'product_type', 'expected_amount', 'net_paid_amount', 'outstanding_amount'],
1041
+ filter: ['eq', 'product_type', 'recurring']
1042
+ )
1043
+
1044
+ # Query outstanding invoices
1045
+ Pike13::Reporting::InvoiceItems.query(
1046
+ fields: ['invoice_number', 'invoice_payer_name', 'product_name', 'expected_amount', 'outstanding_amount'],
1047
+ filter: ['gt', 'outstanding_amount', 0],
1048
+ sort: ['outstanding_amount-']
1049
+ )
1050
+
1051
+ # Query items with discounts
1052
+ Pike13::Reporting::InvoiceItems.query(
1053
+ fields: ['product_name', 'gross_amount', 'discounts_amount', 'coupons_amount', 'expected_amount'],
1054
+ filter: ['gt', 'discounts_amount', 0]
1055
+ )
1056
+
1057
+ # Track revenue by product
1058
+ Pike13::Reporting::InvoiceItems.query(
1059
+ fields: ['product_name', 'gross_amount', 'expected_revenue_amount', 'expected_tax_amount', 'net_paid_revenue_amount']
1060
+ )
1061
+
1062
+ # Query by revenue category
1063
+ Pike13::Reporting::InvoiceItems.query(
1064
+ fields: ['revenue_category', 'product_name', 'expected_amount', 'net_paid_amount'],
1065
+ filter: ['not_null', 'revenue_category']
1066
+ )
1067
+
1068
+ # Group by product to analyze sales
1069
+ Pike13::Reporting::InvoiceItems.query(
1070
+ fields: ['invoice_item_count', 'total_expected_amount', 'total_net_paid_amount', 'total_outstanding_amount'],
1071
+ group: 'product_name'
1072
+ )
1073
+
1074
+ # Group by product type
1075
+ Pike13::Reporting::InvoiceItems.query(
1076
+ fields: ['invoice_item_count', 'total_gross_amount', 'total_discounts_amount', 'total_expected_amount'],
1077
+ group: 'product_type'
1078
+ )
1079
+
1080
+ # Monthly revenue analysis
1081
+ Pike13::Reporting::InvoiceItems.query(
1082
+ fields: ['invoice_item_count', 'total_expected_revenue_amount', 'total_net_paid_revenue_amount'],
1083
+ group: 'issued_month_start_date'
1084
+ )
1085
+ ```
1086
+
1087
+ **Available Detail Fields** (when not grouping):
1088
+ - Invoice Item: `invoice_item_id`, `invoice_id`, `invoice_number`, `invoice_state`, `invoice_autobill`
1089
+ - Product: `product_id`, `product_name`, `product_name_at_sale`, `product_type`, `grants_membership`
1090
+ - Amounts: `gross_amount`, `expected_amount`, `expected_revenue_amount`, `expected_tax_amount`
1091
+ - Discounts: `discounts_amount`, `coupons_amount`, `coupon_code`, `adjustments_amount`, `discount_type`
1092
+ - Payments: `net_paid_amount`, `net_paid_revenue_amount`, `net_paid_tax_amount`, `payments_amount`, `refunds_amount`
1093
+ - Outstanding: `outstanding_amount`, `outstanding_revenue_amount`, `outstanding_tax_amount`
1094
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_email`, `invoice_payer_phone`, `invoice_payer_home_location`
1095
+ - Dates: `issued_at`, `issued_date`, `closed_at`, `closed_date`, `invoice_due_date`, `days_since_invoice_due`
1096
+ - Tax: `tax_types`, `tax_types_extended`
1097
+ - Commission: `commission_recipient_name`
1098
+ - Recipients: `recipient_names`
1099
+ - Transactions: `failed_transactions`, `refunded_transactions`, `voided_transactions`
1100
+ - Purchase Requests: `purchase_order_number`, `purchase_request_state`, `purchase_request_message`, `purchase_request_cancel_reason`
1101
+ - Retail: `retail_options`, `retail_add_ons`
1102
+ - Other: `revenue_category`, `sale_location_name`, `plan_id`, `created_by_client`, `created_by_name`
1103
+ - See `Pike13::Reporting::InvoiceItems::DETAIL_FIELDS` for the full list
1104
+
1105
+ **Available Summary Fields** (when grouping):
1106
+ - Counts: `invoice_item_count`, `invoice_count`, `grants_membership_count`, `total_count`
1107
+ - Amounts: `total_gross_amount`, `total_expected_amount`, `total_expected_revenue_amount`, `total_expected_tax_amount`
1108
+ - Discounts: `total_discounts_amount`, `total_coupons_amount`, `total_adjustments_amount`
1109
+ - Payments: `total_net_paid_amount`, `total_net_paid_revenue_amount`, `total_net_paid_tax_amount`, `total_payments_amount`, `total_refunds_amount`
1110
+ - Outstanding: `total_outstanding_amount`, `total_outstanding_revenue_amount`, `total_outstanding_tax_amount`
1111
+ - See `Pike13::Reporting::InvoiceItems::SUMMARY_FIELDS` for the full list
1112
+
1113
+ **Available Groupings**:
1114
+ - Product: `product_id`, `product_name`, `product_name_at_sale`, `product_type`, `grants_membership`, `plan_id`
1115
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_autobill`, `invoice_due_date`
1116
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_home_location`, `invoice_payer_primary_staff_name_at_sale`
1117
+ - Dates - Issued: `issued_date`, `issued_month_start_date`, `issued_quarter_start_date`, `issued_year_start_date`
1118
+ - Dates - Due: `due_month_start_date`, `due_quarter_start_date`, `due_year_start_date`
1119
+ - Dates - Closed: `closed_date`, `closed_month_start_date`, `closed_quarter_start_date`, `closed_year_start_date`
1120
+ - Week groupings: `issued_week_mon_start_date`, `issued_week_sun_start_date`, `due_week_mon_start_date`, `due_week_sun_start_date`, `closed_week_mon_start_date`, `closed_week_sun_start_date`
1121
+ - Discounts: `discount_type`, `coupon_code`
1122
+ - Other: `revenue_category`, `sale_location_name`, `commission_recipient_name`, `created_by_client`, `created_by_name`, `purchase_request_state`
1123
+ - Business: `business_id`, `business_name`, `business_subdomain`
1124
+
1125
+ #### Invoice Item Transactions
1126
+
1127
+ Item-level details of transactions (payments and refunds). Payments and refunds are performed against the invoice, not the invoice item.
1128
+
1129
+ ```ruby
1130
+ # Basic query - get transaction details
1131
+ Pike13::Reporting::InvoiceItemTransactions.query(
1132
+ fields: ['transaction_id', 'invoice_number', 'transaction_type', 'transaction_amount', 'transaction_state']
1133
+ )
1134
+
1135
+ # Query by payment method
1136
+ Pike13::Reporting::InvoiceItemTransactions.query(
1137
+ fields: ['transaction_date', 'payment_method', 'transaction_amount', 'invoice_payer_name', 'product_name'],
1138
+ filter: ['eq', 'payment_method', 'creditcard']
1139
+ )
1140
+
1141
+ # Query successful payments
1142
+ Pike13::Reporting::InvoiceItemTransactions.query(
1143
+ fields: ['transaction_date', 'invoice_number', 'payment_method', 'net_paid_amount', 'payment_method_detail'],
1144
+ filter: [
1145
+ 'and',
1146
+ [
1147
+ ['eq', 'transaction_type', 'payment'],
1148
+ ['eq', 'transaction_state', 'settled']
1149
+ ]
1150
+ ]
1151
+ )
1152
+
1153
+ # Query failed transactions
1154
+ Pike13::Reporting::InvoiceItemTransactions.query(
1155
+ fields: ['failed_date', 'invoice_payer_name', 'payment_method', 'transaction_amount', 'error_message'],
1156
+ filter: ['eq', 'transaction_state', 'failed'],
1157
+ sort: ['failed_date-']
1158
+ )
1159
+
1160
+ # Track refunds
1161
+ Pike13::Reporting::InvoiceItemTransactions.query(
1162
+ fields: ['transaction_date', 'invoice_number', 'refunds_amount', 'invoice_payer_name', 'payment_transaction_id'],
1163
+ filter: ['eq', 'transaction_type', 'refund']
1164
+ )
1165
+
1166
+ # Analyze revenue by product
1167
+ Pike13::Reporting::InvoiceItemTransactions.query(
1168
+ fields: ['product_name', 'transaction_amount', 'net_paid_revenue_amount', 'net_paid_tax_amount', 'payment_method']
1169
+ )
1170
+
1171
+ # Group by payment method to analyze payment trends
1172
+ Pike13::Reporting::InvoiceItemTransactions.query(
1173
+ fields: ['transaction_count', 'total_net_paid_amount', 'settled_count', 'failed_count'],
1174
+ group: 'payment_method'
1175
+ )
1176
+
1177
+ # Group by credit card type
1178
+ Pike13::Reporting::InvoiceItemTransactions.query(
1179
+ fields: ['transaction_count', 'total_net_visa_paid_amount', 'total_net_mastercard_paid_amount', 'total_net_american_express_paid_amount', 'total_net_discover_paid_amount'],
1180
+ group: 'credit_card_name'
1181
+ )
1182
+
1183
+ # Monthly transaction summary
1184
+ Pike13::Reporting::InvoiceItemTransactions.query(
1185
+ fields: ['transaction_count', 'total_payments_amount', 'total_refunds_amount', 'total_net_paid_revenue_amount'],
1186
+ group: 'transaction_month_start_date'
1187
+ )
1188
+ ```
1189
+
1190
+ **Available Detail Fields** (when not grouping):
1191
+ - Transaction: `transaction_id`, `transaction_type`, `transaction_state`, `transaction_amount`, `transaction_at`, `transaction_date`, `transaction_autopay`
1192
+ - Payment Info: `payment_method`, `payment_method_detail`, `processing_method`, `processor_transaction_id`, `credit_card_name`, `external_payment_name`
1193
+ - Amounts: `net_paid_amount`, `net_paid_revenue_amount`, `net_paid_tax_amount`, `payments_amount`, `refunds_amount`
1194
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_autobill`, `invoice_due_date`, `invoice_item_id`
1195
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_email`, `invoice_payer_phone`, `invoice_payer_home_location`
1196
+ - Product: `product_id`, `product_name`, `product_name_at_sale`, `product_type`, `grants_membership`, `plan_id`
1197
+ - Failed: `failed_at`, `failed_date`, `error_message`
1198
+ - Voided: `voided_at`
1199
+ - Refund: `payment_transaction_id` (original payment for refund)
1200
+ - Other: `revenue_category`, `sale_location_name`, `commission_recipient_name`, `created_by_name`
1201
+ - See `Pike13::Reporting::InvoiceItemTransactions::DETAIL_FIELDS` for the full list
1202
+
1203
+ **Available Summary Fields** (when grouping):
1204
+ - Counts: `transaction_count`, `settled_count`, `failed_count`, `transaction_autopay_count`, `invoice_count`, `invoice_item_count`, `grants_membership_count`, `total_count`
1205
+ - Amounts: `total_net_paid_amount`, `total_net_paid_revenue_amount`, `total_net_paid_tax_amount`, `total_payments_amount`, `total_refunds_amount`
1206
+ - By Payment Method: `total_net_cash_paid_amount`, `total_net_check_paid_amount`, `total_net_credit_paid_amount`, `total_net_ach_paid_amount`, `total_net_external_paid_amount`
1207
+ - By Card Type: `total_net_visa_paid_amount`, `total_net_mastercard_paid_amount`, `total_net_american_express_paid_amount`, `total_net_discover_paid_amount`, `total_net_other_credit_card_paid_amount`
1208
+ - By Processing Method: `total_net_amex_processing_paid_amount`, `total_net_global_pay_processing_paid_amount`, `total_net_other_processing_paid_amount`
1209
+ - See `Pike13::Reporting::InvoiceItemTransactions::SUMMARY_FIELDS` for the full list
1210
+
1211
+ **Available Groupings**:
1212
+ - Transaction: `transaction_id`, `transaction_type`, `transaction_state`, `transaction_autopay`, `transaction_date`
1213
+ - Dates - Transaction: `transaction_month_start_date`, `transaction_quarter_start_date`, `transaction_year_start_date`
1214
+ - Dates - Failed: `failed_date`, `failed_month_start_date`, `failed_quarter_start_date`, `failed_year_start_date`
1215
+ - Week groupings: `transaction_week_mon_start_date`, `transaction_week_sun_start_date`, `failed_week_mon_start_date`, `failed_week_sun_start_date`
1216
+ - Payment: `payment_method`, `processing_method`, `credit_card_name`, `external_payment_name`
1217
+ - Invoice: `invoice_id`, `invoice_number`, `invoice_state`, `invoice_autobill`, `invoice_due_date`, `invoice_item_id`
1218
+ - Payer: `invoice_payer_id`, `invoice_payer_name`, `invoice_payer_home_location`, `invoice_payer_primary_staff_name_at_sale`
1219
+ - Product: `product_id`, `product_name`, `product_name_at_sale`, `product_type`, `grants_membership`, `plan_id`
1220
+ - Other: `revenue_category`, `sale_location_name`, `commission_recipient_name`, `created_by_name`
1221
+ - Business: `business_id`, `business_name`, `business_subdomain`
1222
+
1223
+ #### Pays
1224
+
1225
+ Details of staff member pay, pay rates, services, and hours.
1226
+
1227
+ ```ruby
1228
+ # Basic query - get pay details
1229
+ Pike13::Reporting::Pays.query(
1230
+ fields: ['pay_id', 'staff_name', 'pay_type', 'final_pay_amount', 'pay_state']
1231
+ )
1232
+
1233
+ # Query by staff member
1234
+ Pike13::Reporting::Pays.query(
1235
+ fields: ['staff_name', 'service_name', 'service_date', 'final_pay_amount', 'service_hours'],
1236
+ filter: ['eq', 'staff_id', 12345],
1237
+ sort: ['service_date-']
1238
+ )
1239
+
1240
+ # Query pending pay approvals
1241
+ Pike13::Reporting::Pays.query(
1242
+ fields: ['staff_name', 'pay_description', 'final_pay_amount', 'pay_recorded_at'],
1243
+ filter: ['eq', 'pay_state', 'pending']
1244
+ )
1245
+
1246
+ # Track pay by service type
1247
+ Pike13::Reporting::Pays.query(
1248
+ fields: ['service_name', 'service_type', 'staff_name', 'base_pay_amount', 'per_head_pay_amount', 'tiered_pay_amount', 'final_pay_amount']
1249
+ )
1250
+
1251
+ # Query by pay period
1252
+ Pike13::Reporting::Pays.query(
1253
+ fields: ['staff_name', 'service_date', 'final_pay_amount', 'pay_period_start_date', 'pay_period_end_date'],
1254
+ filter: ['eq', 'pay_period', '2024-10-01..2024-10-31']
1255
+ )
1256
+
1257
+ # Analyze pay by type
1258
+ Pike13::Reporting::Pays.query(
1259
+ fields: ['pay_type', 'pay_description', 'final_pay_amount', 'staff_name'],
1260
+ filter: ['in', 'pay_type', ['service', 'commission', 'tip']]
1261
+ )
1262
+
1263
+ # Group by staff member to analyze total pay
1264
+ Pike13::Reporting::Pays.query(
1265
+ fields: ['pay_count', 'total_final_pay_amount', 'total_service_hours', 'total_base_pay_amount'],
1266
+ group: 'staff_name'
1267
+ )
1268
+
1269
+ # Group by service to analyze pay distribution
1270
+ Pike13::Reporting::Pays.query(
1271
+ fields: ['service_count', 'pay_count', 'total_final_pay_amount'],
1272
+ group: 'service_name'
1273
+ )
1274
+
1275
+ # Group by pay type
1276
+ Pike13::Reporting::Pays.query(
1277
+ fields: ['pay_count', 'total_final_pay_amount', 'total_base_pay_amount', 'total_per_head_pay_amount', 'total_tiered_pay_amount'],
1278
+ group: 'pay_type'
1279
+ )
1280
+ ```
1281
+
1282
+ **Available Detail Fields** (when not grouping):
1283
+ - Pay: `pay_id`, `pay_type`, `pay_state`, `pay_description`, `pay_period`, `pay_period_start_date`, `pay_period_end_date`
1284
+ - Amounts: `final_pay_amount`, `base_pay_amount`, `per_head_pay_amount`, `tiered_pay_amount`
1285
+ - Staff: `staff_id`, `staff_name`, `staff_home_location_name`
1286
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_date`, `service_location_name`, `service_hours`
1287
+ - Recorded: `pay_recorded_at`
1288
+ - Reviewed: `pay_reviewed_at`, `pay_reviewed_date`, `pay_reviewed_by_id`, `pay_reviewed_by_name`
1289
+ - Other: `revenue_category`
1290
+ - See `Pike13::Reporting::Pays::DETAIL_FIELDS` for the full list
1291
+
1292
+ **Available Summary Fields** (when grouping):
1293
+ - Counts: `pay_count`, `service_count`, `total_count`
1294
+ - Amounts: `total_final_pay_amount`, `total_base_pay_amount`, `total_per_head_pay_amount`, `total_tiered_pay_amount`
1295
+ - Hours: `total_service_hours`
1296
+ - See `Pike13::Reporting::Pays::SUMMARY_FIELDS` for the full list
1297
+
1298
+ **Available Groupings**:
1299
+ - Pay: `pay_type`, `pay_state`, `pay_period`, `pay_reviewed_date`, `pay_reviewed_by_id`, `pay_reviewed_by_name`
1300
+ - Staff: `staff_id`, `staff_name`, `staff_home_location_name`
1301
+ - Service: `service_id`, `service_name`, `service_type`, `service_category`, `service_date`, `service_location_name`
1302
+ - Other: `revenue_category`
1303
+ - Business: `business_id`, `business_name`, `business_subdomain`
1304
+
1305
+ #### Person Plans
1306
+
1307
+ Comprehensive data about passes and plans that are available for use or on hold.
1308
+
1309
+ ```ruby
1310
+ # Basic query - get all person plans
1311
+ Pike13::Reporting::PersonPlans.query(
1312
+ fields: ['person_plan_id', 'full_name', 'plan_name', 'is_available', 'start_date', 'end_date']
1313
+ )
1314
+
1315
+ # Query available memberships
1316
+ Pike13::Reporting::PersonPlans.query(
1317
+ fields: ['full_name', 'plan_name', 'start_date', 'end_date', 'remaining_visit_count'],
1318
+ filter: [
1319
+ 'and',
1320
+ [
1321
+ ['eq', 'is_available', true],
1322
+ ['eq', 'grants_membership', true]
1323
+ ]
1324
+ ]
1325
+ )
1326
+
1327
+ # Query plans on hold
1328
+ Pike13::Reporting::PersonPlans.query(
1329
+ fields: ['full_name', 'plan_name', 'last_hold_start_date', 'last_hold_end_date', 'last_hold_by'],
1330
+ filter: ['eq', 'is_on_hold', true]
1331
+ )
1332
+
1333
+ # Query plans with past due invoices
1334
+ Pike13::Reporting::PersonPlans.query(
1335
+ fields: ['full_name', 'plan_name', 'latest_invoice_due_date', 'latest_invoice_item_amount'],
1336
+ filter: ['eq', 'latest_invoice_past_due', true]
1337
+ )
1338
+
1339
+ # Track plan usage and visits
1340
+ Pike13::Reporting::PersonPlans.query(
1341
+ fields: ['full_name', 'plan_name', 'used_visit_count', 'remaining_visit_count', 'lifetime_used_visit_count'],
1342
+ filter: ['gt', 'used_visit_count', 0]
1343
+ )
1344
+
1345
+ # Group by plan type
1346
+ Pike13::Reporting::PersonPlans.query(
1347
+ fields: ['person_plan_count', 'is_available_count', 'is_on_hold_count', 'is_canceled_count'],
1348
+ group: 'plan_type'
1349
+ )
1350
+
1351
+ # Analyze plan retention
1352
+ Pike13::Reporting::PersonPlans.query(
1353
+ fields: [
1354
+ 'person_plan_count',
1355
+ 'visited_count',
1356
+ 'visited_percent',
1357
+ 'next_plan_count',
1358
+ 'next_plan_percent'
1359
+ ],
1360
+ group: 'plan_name'
1361
+ )
1362
+
1363
+ # Track first-time members
1364
+ Pike13::Reporting::PersonPlans.query(
1365
+ fields: ['full_name', 'plan_name', 'start_date', 'first_visit_date', 'start_date_to_first_visit'],
1366
+ filter: ['eq', 'is_first_plan', true]
1367
+ )
1368
+ ```
1369
+
1370
+ **Available Detail Fields** (when not grouping):
1371
+ - Plan: `person_plan_id`, `plan_id`, `plan_name`, `plan_type`, `plan_product_id`, `product_name`
1372
+ - Person: `person_id`, `full_name`, `first_name`, `last_name`, `email`, `home_location_name`
1373
+ - Dates: `start_date`, `end_date`, `last_usable_date`, `first_visit_date`, `last_visit_date`
1374
+ - Status: `is_available`, `is_on_hold`, `is_canceled`, `is_exhausted`, `is_ended`, `is_deactivated`
1375
+ - Visits: `allowed_visit_count`, `used_visit_count`, `remaining_visit_count`, `lifetime_used_visit_count`
1376
+ - Membership: `grants_membership`, `is_first_membership`, `is_first_plan`
1377
+ - Billing: `base_price`, `invoice_interval_count`, `invoice_interval_unit`, `commitment_length`
1378
+ - Invoice: `latest_invoice_due_date`, `latest_invoice_item_amount`, `latest_invoice_past_due`, `latest_invoice_autobill`
1379
+ - Hold: `last_hold_start_date`, `last_hold_end_date`, `last_hold_by`, `is_last_hold_indefinite`
1380
+ - Next Plan: `next_plan_id`, `next_plan_name`, `next_plan_type`, `next_plan_start_date`
1381
+ - Timing: `start_date_to_first_visit`, `first_visit_to_next_plan`, `last_visit_to_next_plan`
1382
+ - See `Pike13::Reporting::PersonPlans::DETAIL_FIELDS` for the full list (100+ fields)
1383
+
1384
+ **Available Summary Fields** (when grouping):
1385
+ - Counts: `person_plan_count`, `person_count`, `plan_count`, `visited_count`, `visited_percent`
1386
+ - Availability: `is_available_count`, `is_on_hold_count`, `is_canceled_count`
1387
+ - Membership: `grants_membership_count`, `is_first_membership_count`, `is_first_plan_count`
1388
+ - Next Plan: `next_plan_count`, `next_plan_percent`, `next_plan_within_week_percent`
1389
+ - Usage: `total_used_visit_count`, `total_lifetime_used_visit_count`
1390
+ - Averages: `avg_start_date_to_first_visit`, `avg_first_visit_to_next_plan`, `avg_last_visit_to_next_plan`
1391
+ - See `Pike13::Reporting::PersonPlans::SUMMARY_FIELDS` for the full list
1392
+
1393
+ **Available Groupings**:
1394
+ - Plan: `plan_id`, `plan_name`, `plan_type`, `product_id`, `product_name`, `plan_location_name`
1395
+ - Person: `person_id`, `full_name`, `home_location_name`, `primary_staff_name`
1396
+ - Status: `is_available`, `is_on_hold`, `is_canceled`, `grants_membership`, `is_first_plan`
1397
+ - Dates: `start_date`, `start_month_start_date`, `first_visit_date`, `first_visit_month_start_date`, `last_visit_date`
1398
+ - Invoice: `latest_invoice_past_due`, `latest_invoice_autobill`, `latest_invoice_due_date`
1399
+ - Business: `business_id`, `business_name`, `business_subdomain`, `revenue_category`
1400
+
1401
+ #### Staff Members
1402
+
1403
+ All staff member data — from tenure and events to birthdays and custom fields. Includes all staff members past and present.
1404
+
1405
+ ```ruby
1406
+ # Basic query - get all staff members
1407
+ Pike13::Reporting::StaffMembers.query(
1408
+ fields: ['person_id', 'full_name', 'email', 'role', 'person_state']
1409
+ )
1410
+
1411
+ # Query active staff members with event counts
1412
+ Pike13::Reporting::StaffMembers.query(
1413
+ fields: ['full_name', 'email', 'role', 'tenure', 'future_events', 'past_events'],
1414
+ filter: ['eq', 'person_state', 'active'],
1415
+ sort: ['tenure-']
1416
+ )
1417
+
1418
+ # Find staff members shown to clients
1419
+ Pike13::Reporting::StaffMembers.query(
1420
+ fields: ['full_name', 'email', 'role', 'home_location_name'],
1421
+ filter: ['eq', 'show_to_clients', true]
1422
+ )
1423
+
1424
+ # Query staff members by role
1425
+ Pike13::Reporting::StaffMembers.query(
1426
+ fields: ['full_name', 'email', 'tenure', 'future_events'],
1427
+ filter: ['in', 'role', ['manager', 'owner', 'primary_owner']]
1428
+ )
1429
+
1430
+ # Find staff with upcoming birthdays
1431
+ Pike13::Reporting::StaffMembers.query(
1432
+ fields: ['full_name', 'email', 'birthdate', 'days_until_birthday'],
1433
+ filter: ['lte', 'days_until_birthday', 30],
1434
+ sort: ['days_until_birthday+']
1435
+ )
1436
+
1437
+ # Track staff tenure
1438
+ Pike13::Reporting::StaffMembers.query(
1439
+ fields: ['full_name', 'staff_since_date', 'tenure', 'tenure_group', 'past_events'],
1440
+ filter: ['eq', 'person_state', 'active'],
1441
+ sort: ['tenure-']
1442
+ )
1443
+
1444
+ # Find staff who are also clients
1445
+ Pike13::Reporting::StaffMembers.query(
1446
+ fields: ['full_name', 'email', 'role', 'home_location_name'],
1447
+ filter: ['eq', 'also_client', true]
1448
+ )
1449
+
1450
+ # Group by role to analyze staff composition
1451
+ Pike13::Reporting::StaffMembers.query(
1452
+ fields: ['person_count', 'total_future_events', 'total_past_events'],
1453
+ group: 'role'
1454
+ )
1455
+
1456
+ # Group by tenure group to analyze staff retention
1457
+ Pike13::Reporting::StaffMembers.query(
1458
+ fields: ['person_count', 'total_future_events', 'also_client_count'],
1459
+ group: 'tenure_group'
1460
+ )
1461
+
1462
+ # Group by location to see staff distribution
1463
+ Pike13::Reporting::StaffMembers.query(
1464
+ fields: ['person_count', 'total_future_events', 'total_past_events'],
1465
+ group: 'home_location_name'
1466
+ )
1467
+ ```
1468
+
1469
+ **Available Detail Fields** (when not grouping):
1470
+ - Person: `person_id`, `full_name`, `first_name`, `last_name`, `middle_name`, `email`, `phone`, `birthdate`, `age`, `days_until_birthday`
1471
+ - Address: `address`, `street_address`, `street_address2`, `city`, `state_code`, `postal_code`, `country_code`
1472
+ - Staff: `role`, `person_state`, `show_to_clients`, `also_client`, `home_location_id`, `home_location_name`
1473
+ - Tenure: `staff_since_date`, `tenure`, `tenure_group`
1474
+ - Events: `future_events`, `past_events`, `attendance_not_completed_events`
1475
+ - Custom: `custom_fields`
1476
+ - See `Pike13::Reporting::StaffMembers::DETAIL_FIELDS` for the full list
1477
+
1478
+ **Available Summary Fields** (when grouping):
1479
+ - Counts: `person_count`, `also_client_count`, `demoted_staff_count`, `total_count`
1480
+ - Events: `total_future_events`, `total_past_events`, `total_attendance_not_completed_events`
1481
+ - See `Pike13::Reporting::StaffMembers::SUMMARY_FIELDS` for the full list
1482
+
1483
+ **Available Groupings**:
1484
+ - Staff: `role`, `person_state`, `show_to_clients`, `also_client`, `home_location_name`
1485
+ - Tenure: `staff_since_date`, `staff_since_month_start_date`, `staff_since_quarter_start_date`, `staff_since_week_mon_start_date`, `staff_since_week_sun_start_date`, `staff_since_year_start_date`, `tenure_group`
1486
+ - Demographics: `age`
1487
+ - Business: `business_id`, `business_name`, `business_subdomain`
1488
+
584
1489
  ## Error Handling
585
1490
 
586
1491
  ```ruby
@@ -615,6 +1520,7 @@ bundle install
615
1520
 
616
1521
  # Run tests
617
1522
  bundle exec rake test
1523
+ ```
618
1524
 
619
1525
  ## Contributing
620
1526
 
@@ -626,9 +1532,10 @@ bundle exec rake test
626
1532
 
627
1533
  ## License
628
1534
 
629
- MIT License
1535
+ [MIT License](LICENSE.txt)
630
1536
 
631
1537
  ## Links
632
1538
 
633
- - [Pike13 API Documentation](https://developer.pike13.com/docs/api/v2)
634
- - [Pike13 Website](https://www.pike13.com/)
1539
+ - **[Pike13 Core API Documentation](https://developer.pike13.com/docs/api/v2)** - Core API (v2) endpoints
1540
+ - **[Pike13 Reporting API Documentation](https://developer.pike13.com/docs/reporting/v3)** - Reporting API (v3) endpoints
1541
+ - **[Pike13 Website](https://www.pike13.com/)** - Official website