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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +67 -116
- data/README.md +1222 -315
- data/lib/pike13/api/v2/account.rb +19 -0
- data/lib/pike13/api/v2/desk/booking.rb +10 -0
- data/lib/pike13/api/v2/desk/business.rb +2 -1
- data/lib/pike13/api/v2/desk/event_occurrence.rb +2 -2
- data/lib/pike13/api/v2/desk/person.rb +5 -3
- data/lib/pike13/api/v2/desk/plan.rb +2 -2
- data/lib/pike13/api/v2/desk/plan_product.rb +2 -2
- data/lib/pike13/api/v2/desk/service.rb +2 -2
- data/lib/pike13/api/v2/desk/visit.rb +2 -2
- data/lib/pike13/api/v2/front/branding.rb +2 -1
- data/lib/pike13/api/v2/front/business.rb +2 -1
- data/lib/pike13/api/v2/front/event_occurrence.rb +2 -2
- data/lib/pike13/api/v2/front/plan_product.rb +2 -2
- data/lib/pike13/api/v2/front/service.rb +2 -2
- data/lib/pike13/api/v2/front/visit.rb +2 -2
- data/lib/pike13/api/v3/desk/base.rb +46 -0
- data/lib/pike13/api/v3/desk/clients.rb +180 -0
- data/lib/pike13/api/v3/desk/enrollments.rb +203 -0
- data/lib/pike13/api/v3/desk/event_occurrence_staff_members.rb +170 -0
- data/lib/pike13/api/v3/desk/event_occurrences.rb +154 -0
- data/lib/pike13/api/v3/desk/invoice_item_transactions.rb +189 -0
- data/lib/pike13/api/v3/desk/invoice_items.rb +193 -0
- data/lib/pike13/api/v3/desk/invoices.rb +167 -0
- data/lib/pike13/api/v3/desk/monthly_business_metrics.rb +151 -0
- data/lib/pike13/api/v3/desk/pays.rb +128 -0
- data/lib/pike13/api/v3/desk/person_plans.rb +265 -0
- data/lib/pike13/api/v3/desk/staff_members.rb +127 -0
- data/lib/pike13/api/v3/desk/transactions.rb +169 -0
- data/lib/pike13/http_client.rb +4 -1
- data/lib/pike13/http_client_v3.rb +101 -0
- data/lib/pike13/validators.rb +136 -0
- data/lib/pike13/version.rb +1 -1
- data/lib/pike13.rb +26 -7
- metadata +17 -2
- data/lib/pike13/api/v2/account/me.rb +0 -20
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pike13
|
|
4
|
+
module API
|
|
5
|
+
module V3
|
|
6
|
+
module Desk
|
|
7
|
+
# Person Plans resource
|
|
8
|
+
# Comprehensive data about passes and plans that are available for use or on hold
|
|
9
|
+
#
|
|
10
|
+
# @example Basic query
|
|
11
|
+
# Pike13::Reporting::PersonPlans.query(
|
|
12
|
+
# fields: ['person_plan_id', 'full_name', 'plan_name', 'is_available', 'start_date']
|
|
13
|
+
# )
|
|
14
|
+
#
|
|
15
|
+
# @example Query available memberships
|
|
16
|
+
# Pike13::Reporting::PersonPlans.query(
|
|
17
|
+
# fields: ['full_name', 'plan_name', 'start_date', 'end_date', 'remaining_visit_count'],
|
|
18
|
+
# filter: [
|
|
19
|
+
# 'and',
|
|
20
|
+
# [
|
|
21
|
+
# ['eq', 'is_available', true],
|
|
22
|
+
# ['eq', 'grants_membership', true]
|
|
23
|
+
# ]
|
|
24
|
+
# ]
|
|
25
|
+
# )
|
|
26
|
+
#
|
|
27
|
+
# @example Group by plan type
|
|
28
|
+
# Pike13::Reporting::PersonPlans.query(
|
|
29
|
+
# fields: ['person_plan_count', 'is_available_count', 'is_on_hold_count'],
|
|
30
|
+
# group: 'plan_type'
|
|
31
|
+
# )
|
|
32
|
+
class PersonPlans < Base
|
|
33
|
+
class << self
|
|
34
|
+
# Execute a person plans query
|
|
35
|
+
#
|
|
36
|
+
# @param fields [Array<String>] Fields to return (detail or summary fields)
|
|
37
|
+
# @param filter [Array, nil] Filter criteria (optional)
|
|
38
|
+
# @param group [String, nil] Grouping field (optional)
|
|
39
|
+
# @param sort [Array<String>, nil] Sort order (optional)
|
|
40
|
+
# @param page [Hash, nil] Pagination options (optional)
|
|
41
|
+
# @param total_count [Boolean] Whether to return total count (optional)
|
|
42
|
+
# @return [Hash] Query result with rows, fields, and metadata
|
|
43
|
+
#
|
|
44
|
+
# @see https://developer.pike13.com/docs/api/v3/reports/person-plans
|
|
45
|
+
def query(fields:, filter: nil, group: nil, sort: nil, page: nil, total_count: nil)
|
|
46
|
+
query_params = { fields: fields }
|
|
47
|
+
query_params[:filter] = filter if filter
|
|
48
|
+
query_params[:group] = group if group
|
|
49
|
+
query_params[:sort] = sort if sort
|
|
50
|
+
query_params[:page] = page if page
|
|
51
|
+
query_params[:total_count] = total_count if total_count
|
|
52
|
+
|
|
53
|
+
super("person_plans", query_params)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Available detail fields (when not grouping)
|
|
57
|
+
DETAIL_FIELDS = %w[
|
|
58
|
+
account_manager_emails
|
|
59
|
+
account_manager_names
|
|
60
|
+
account_manager_phones
|
|
61
|
+
allowed_visit_count
|
|
62
|
+
are_visits_shared
|
|
63
|
+
base_price
|
|
64
|
+
business_id
|
|
65
|
+
business_name
|
|
66
|
+
business_subdomain
|
|
67
|
+
canceled_at
|
|
68
|
+
canceled_by
|
|
69
|
+
canceled_by_account_id
|
|
70
|
+
cancellation_fee_amount
|
|
71
|
+
charged_cancellation_fee_amount
|
|
72
|
+
commitment_length
|
|
73
|
+
completed_visit_count
|
|
74
|
+
currency_code
|
|
75
|
+
deactivated_at
|
|
76
|
+
email
|
|
77
|
+
end_date
|
|
78
|
+
exhausted_at
|
|
79
|
+
first_name
|
|
80
|
+
first_visit_date
|
|
81
|
+
first_visit_day
|
|
82
|
+
first_visit_instructor_names
|
|
83
|
+
first_visit_time
|
|
84
|
+
first_visit_to_next_plan
|
|
85
|
+
franchise_id
|
|
86
|
+
full_name
|
|
87
|
+
grants_membership
|
|
88
|
+
has_cancellation_fee
|
|
89
|
+
home_location_name
|
|
90
|
+
invoice_interval_count
|
|
91
|
+
invoice_interval_unit
|
|
92
|
+
is_available
|
|
93
|
+
is_canceled
|
|
94
|
+
is_cancellation_fee_charged
|
|
95
|
+
is_complimentary_pass
|
|
96
|
+
is_deactivated
|
|
97
|
+
is_deleted
|
|
98
|
+
is_ended
|
|
99
|
+
is_exhausted
|
|
100
|
+
is_first_membership
|
|
101
|
+
is_first_plan
|
|
102
|
+
is_last_hold_indefinite
|
|
103
|
+
is_on_hold
|
|
104
|
+
is_primary_participant
|
|
105
|
+
key
|
|
106
|
+
last_hold_by
|
|
107
|
+
last_hold_by_account_id
|
|
108
|
+
last_hold_end_date
|
|
109
|
+
last_hold_start_date
|
|
110
|
+
last_name
|
|
111
|
+
last_usable_date
|
|
112
|
+
last_visit_date
|
|
113
|
+
last_visit_day
|
|
114
|
+
last_visit_time
|
|
115
|
+
last_visit_to_next_plan
|
|
116
|
+
latest_invoice_autobill
|
|
117
|
+
latest_invoice_due_date
|
|
118
|
+
latest_invoice_item_amount
|
|
119
|
+
latest_invoice_past_due
|
|
120
|
+
lifetime_used_visit_count
|
|
121
|
+
middle_name
|
|
122
|
+
next_plan_grants_membership
|
|
123
|
+
next_plan_id
|
|
124
|
+
next_plan_name
|
|
125
|
+
next_plan_revenue_category
|
|
126
|
+
next_plan_start_date
|
|
127
|
+
next_plan_type
|
|
128
|
+
person_id
|
|
129
|
+
person_plan_id
|
|
130
|
+
plan_id
|
|
131
|
+
plan_location_id
|
|
132
|
+
plan_location_name
|
|
133
|
+
plan_name
|
|
134
|
+
plan_product_id
|
|
135
|
+
plan_type
|
|
136
|
+
primary_staff_name
|
|
137
|
+
product_id
|
|
138
|
+
product_name
|
|
139
|
+
remaining_commitment
|
|
140
|
+
remaining_visit_count
|
|
141
|
+
revenue_category
|
|
142
|
+
rollover_count
|
|
143
|
+
start_date
|
|
144
|
+
start_date_to_first_visit
|
|
145
|
+
start_date_to_next_plan
|
|
146
|
+
stop_renewing_after_commitment
|
|
147
|
+
term_acceptance_required
|
|
148
|
+
term_accepted
|
|
149
|
+
used_for_initial_visit
|
|
150
|
+
used_visit_count
|
|
151
|
+
visit_refresh_interval_count
|
|
152
|
+
visit_refresh_interval_unit
|
|
153
|
+
].freeze
|
|
154
|
+
|
|
155
|
+
# Available summary fields (when grouping)
|
|
156
|
+
SUMMARY_FIELDS = %w[
|
|
157
|
+
avg_first_visit_to_next_plan
|
|
158
|
+
avg_last_visit_to_next_plan
|
|
159
|
+
avg_start_date_to_first_visit
|
|
160
|
+
avg_start_date_to_next_plan
|
|
161
|
+
business_id_summary
|
|
162
|
+
business_subdomain_summary
|
|
163
|
+
grants_membership_count
|
|
164
|
+
has_cancellation_fee_count
|
|
165
|
+
is_available_count
|
|
166
|
+
is_canceled_count
|
|
167
|
+
is_complimentary_pass_count
|
|
168
|
+
is_first_membership_count
|
|
169
|
+
is_first_plan_count
|
|
170
|
+
is_on_hold_count
|
|
171
|
+
latest_invoice_past_due_count
|
|
172
|
+
next_plan_count
|
|
173
|
+
next_plan_grants_membership_percent
|
|
174
|
+
next_plan_on_visit_date_percent
|
|
175
|
+
next_plan_out_of_visited_percent
|
|
176
|
+
next_plan_percent
|
|
177
|
+
next_plan_within_week_percent
|
|
178
|
+
person_count
|
|
179
|
+
person_plan_count
|
|
180
|
+
plan_count
|
|
181
|
+
total_cancellation_fee_amount
|
|
182
|
+
total_charged_cancellation_fee_amount
|
|
183
|
+
total_count
|
|
184
|
+
total_latest_invoice_item_amount
|
|
185
|
+
total_lifetime_used_visit_count
|
|
186
|
+
total_used_for_initial_visit
|
|
187
|
+
total_used_visit_count
|
|
188
|
+
visited_count
|
|
189
|
+
visited_percent
|
|
190
|
+
].freeze
|
|
191
|
+
|
|
192
|
+
# Available grouping fields
|
|
193
|
+
GROUPINGS = %w[
|
|
194
|
+
are_visits_shared
|
|
195
|
+
business_id
|
|
196
|
+
business_name
|
|
197
|
+
business_subdomain
|
|
198
|
+
canceled_by
|
|
199
|
+
canceled_by_account_id
|
|
200
|
+
end_date
|
|
201
|
+
first_visit_date
|
|
202
|
+
first_visit_instructor_names
|
|
203
|
+
first_visit_month_start_date
|
|
204
|
+
first_visit_quarter_start_date
|
|
205
|
+
first_visit_week_mon_start_date
|
|
206
|
+
first_visit_week_sun_start_date
|
|
207
|
+
first_visit_year_start_date
|
|
208
|
+
full_name
|
|
209
|
+
grants_membership
|
|
210
|
+
has_cancellation_fee
|
|
211
|
+
home_location_name
|
|
212
|
+
is_available
|
|
213
|
+
is_canceled
|
|
214
|
+
is_cancellation_fee_charged
|
|
215
|
+
is_complimentary_pass
|
|
216
|
+
is_deleted
|
|
217
|
+
is_first_membership
|
|
218
|
+
is_first_plan
|
|
219
|
+
is_last_hold_indefinite
|
|
220
|
+
is_on_hold
|
|
221
|
+
last_hold_by
|
|
222
|
+
last_hold_by_account_id
|
|
223
|
+
last_hold_end_date
|
|
224
|
+
last_hold_start_date
|
|
225
|
+
last_usable_date
|
|
226
|
+
last_usable_month_start_date
|
|
227
|
+
last_usable_quarter_start_date
|
|
228
|
+
last_usable_week_mon_start_date
|
|
229
|
+
last_usable_week_sun_start_date
|
|
230
|
+
last_usable_year_start_date
|
|
231
|
+
last_visit_date
|
|
232
|
+
last_visit_month_start_date
|
|
233
|
+
last_visit_quarter_start_date
|
|
234
|
+
last_visit_week_mon_start_date
|
|
235
|
+
last_visit_week_sun_start_date
|
|
236
|
+
last_visit_year_start_date
|
|
237
|
+
latest_invoice_autobill
|
|
238
|
+
latest_invoice_due_date
|
|
239
|
+
latest_invoice_past_due
|
|
240
|
+
person_id
|
|
241
|
+
plan_id
|
|
242
|
+
plan_location_id
|
|
243
|
+
plan_location_name
|
|
244
|
+
plan_name
|
|
245
|
+
plan_product_id
|
|
246
|
+
plan_type
|
|
247
|
+
primary_staff_name
|
|
248
|
+
product_id
|
|
249
|
+
product_name
|
|
250
|
+
revenue_category
|
|
251
|
+
start_date
|
|
252
|
+
start_month_start_date
|
|
253
|
+
start_quarter_start_date
|
|
254
|
+
start_week_mon_start_date
|
|
255
|
+
start_week_sun_start_date
|
|
256
|
+
start_year_start_date
|
|
257
|
+
stop_renewing_after_commitment
|
|
258
|
+
used_for_initial_visit
|
|
259
|
+
].freeze
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pike13
|
|
4
|
+
module API
|
|
5
|
+
module V3
|
|
6
|
+
module Desk
|
|
7
|
+
# Staff Members resource
|
|
8
|
+
# All staff member data — from tenure and events to birthdays and custom fields
|
|
9
|
+
#
|
|
10
|
+
# @example Basic query
|
|
11
|
+
# Pike13::Reporting::StaffMembers.query(
|
|
12
|
+
# fields: ['person_id', 'full_name', 'email', 'role', 'person_state']
|
|
13
|
+
# )
|
|
14
|
+
#
|
|
15
|
+
# @example Query active staff members
|
|
16
|
+
# Pike13::Reporting::StaffMembers.query(
|
|
17
|
+
# fields: ['full_name', 'email', 'role', 'tenure', 'future_events'],
|
|
18
|
+
# filter: ['eq', 'person_state', 'active']
|
|
19
|
+
# )
|
|
20
|
+
#
|
|
21
|
+
# @example Group by role
|
|
22
|
+
# Pike13::Reporting::StaffMembers.query(
|
|
23
|
+
# fields: ['person_count', 'total_future_events', 'total_past_events'],
|
|
24
|
+
# group: 'role'
|
|
25
|
+
# )
|
|
26
|
+
class StaffMembers < Base
|
|
27
|
+
class << self
|
|
28
|
+
# Execute a staff members query
|
|
29
|
+
#
|
|
30
|
+
# @param fields [Array<String>] Fields to return (detail or summary fields)
|
|
31
|
+
# @param filter [Array, nil] Filter criteria (optional)
|
|
32
|
+
# @param group [String, nil] Grouping field (optional)
|
|
33
|
+
# @param sort [Array<String>, nil] Sort order (optional)
|
|
34
|
+
# @param page [Hash, nil] Pagination options (optional)
|
|
35
|
+
# @param total_count [Boolean] Whether to return total count (optional)
|
|
36
|
+
# @return [Hash] Query result with rows, fields, and metadata
|
|
37
|
+
#
|
|
38
|
+
# @see https://developer.pike13.com/docs/api/v3/reports/staff_members
|
|
39
|
+
def query(fields:, filter: nil, group: nil, sort: nil, page: nil, total_count: nil)
|
|
40
|
+
query_params = { fields: fields }
|
|
41
|
+
query_params[:filter] = filter if filter
|
|
42
|
+
query_params[:group] = group if group
|
|
43
|
+
query_params[:sort] = sort if sort
|
|
44
|
+
query_params[:page] = page if page
|
|
45
|
+
query_params[:total_count] = total_count if total_count
|
|
46
|
+
|
|
47
|
+
super("staff_members", query_params)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Available detail fields (when not grouping)
|
|
51
|
+
DETAIL_FIELDS = %w[
|
|
52
|
+
address
|
|
53
|
+
age
|
|
54
|
+
also_client
|
|
55
|
+
attendance_not_completed_events
|
|
56
|
+
birthdate
|
|
57
|
+
business_id
|
|
58
|
+
business_name
|
|
59
|
+
business_subdomain
|
|
60
|
+
city
|
|
61
|
+
country_code
|
|
62
|
+
currency_code
|
|
63
|
+
custom_fields
|
|
64
|
+
days_until_birthday
|
|
65
|
+
email
|
|
66
|
+
first_name
|
|
67
|
+
franchise_id
|
|
68
|
+
full_name
|
|
69
|
+
future_events
|
|
70
|
+
home_location_id
|
|
71
|
+
home_location_name
|
|
72
|
+
key
|
|
73
|
+
last_name
|
|
74
|
+
middle_name
|
|
75
|
+
past_events
|
|
76
|
+
person_id
|
|
77
|
+
person_state
|
|
78
|
+
phone
|
|
79
|
+
postal_code
|
|
80
|
+
role
|
|
81
|
+
show_to_clients
|
|
82
|
+
staff_since_date
|
|
83
|
+
state_code
|
|
84
|
+
street_address
|
|
85
|
+
street_address2
|
|
86
|
+
tenure
|
|
87
|
+
tenure_group
|
|
88
|
+
].freeze
|
|
89
|
+
|
|
90
|
+
# Available summary fields (when grouping)
|
|
91
|
+
SUMMARY_FIELDS = %w[
|
|
92
|
+
also_client_count
|
|
93
|
+
business_id_summary
|
|
94
|
+
business_subdomain_summary
|
|
95
|
+
demoted_staff_count
|
|
96
|
+
person_count
|
|
97
|
+
total_attendance_not_completed_events
|
|
98
|
+
total_count
|
|
99
|
+
total_future_events
|
|
100
|
+
total_past_events
|
|
101
|
+
].freeze
|
|
102
|
+
|
|
103
|
+
# Available grouping fields
|
|
104
|
+
GROUPINGS = %w[
|
|
105
|
+
age
|
|
106
|
+
also_client
|
|
107
|
+
business_id
|
|
108
|
+
business_name
|
|
109
|
+
business_subdomain
|
|
110
|
+
home_location_name
|
|
111
|
+
person_state
|
|
112
|
+
role
|
|
113
|
+
show_to_clients
|
|
114
|
+
staff_since_date
|
|
115
|
+
staff_since_month_start_date
|
|
116
|
+
staff_since_quarter_start_date
|
|
117
|
+
staff_since_week_mon_start_date
|
|
118
|
+
staff_since_week_sun_start_date
|
|
119
|
+
staff_since_year_start_date
|
|
120
|
+
tenure_group
|
|
121
|
+
].freeze
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pike13
|
|
4
|
+
module API
|
|
5
|
+
module V3
|
|
6
|
+
module Desk
|
|
7
|
+
# Transactions resource
|
|
8
|
+
# Data about the money moving through your business
|
|
9
|
+
#
|
|
10
|
+
# @example Basic query
|
|
11
|
+
# Pike13::Reporting::Transactions.query(
|
|
12
|
+
# fields: ['transaction_id', 'transaction_date', 'net_paid_amount', 'payment_method']
|
|
13
|
+
# )
|
|
14
|
+
#
|
|
15
|
+
# @example Query by date range
|
|
16
|
+
# Pike13::Reporting::Transactions.query(
|
|
17
|
+
# fields: ['transaction_date', 'net_paid_amount', 'invoice_payer_name', 'payment_method'],
|
|
18
|
+
# filter: ['btw', 'transaction_date', '2024-01-01', '2024-12-31']
|
|
19
|
+
# )
|
|
20
|
+
#
|
|
21
|
+
# @example Group by payment method
|
|
22
|
+
# Pike13::Reporting::Transactions.query(
|
|
23
|
+
# fields: ['total_net_paid_amount', 'transaction_count'],
|
|
24
|
+
# group: 'payment_method'
|
|
25
|
+
# )
|
|
26
|
+
class Transactions < Base
|
|
27
|
+
class << self
|
|
28
|
+
# Execute a transactions query
|
|
29
|
+
#
|
|
30
|
+
# @param fields [Array<String>] Fields to return (detail or summary fields)
|
|
31
|
+
# @param filter [Array, nil] Filter criteria (optional)
|
|
32
|
+
# @param group [String, nil] Grouping field (optional)
|
|
33
|
+
# @param sort [Array<String>, nil] Sort order (optional)
|
|
34
|
+
# @param page [Hash, nil] Pagination options (optional)
|
|
35
|
+
# @param total_count [Boolean] Whether to return total count (optional)
|
|
36
|
+
# @return [Hash] Query result with rows, fields, and metadata
|
|
37
|
+
#
|
|
38
|
+
# @see https://developer.pike13.com/docs/api/v3/reports/transactions
|
|
39
|
+
def query(fields:, filter: nil, group: nil, sort: nil, page: nil, total_count: nil)
|
|
40
|
+
query_params = { fields: fields }
|
|
41
|
+
query_params[:filter] = filter if filter
|
|
42
|
+
query_params[:group] = group if group
|
|
43
|
+
query_params[:sort] = sort if sort
|
|
44
|
+
query_params[:page] = page if page
|
|
45
|
+
query_params[:total_count] = total_count if total_count
|
|
46
|
+
|
|
47
|
+
super("transactions", query_params)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Available detail fields (when not grouping)
|
|
51
|
+
DETAIL_FIELDS = %w[
|
|
52
|
+
business_id
|
|
53
|
+
business_name
|
|
54
|
+
business_subdomain
|
|
55
|
+
commission_recipient_name
|
|
56
|
+
created_by_name
|
|
57
|
+
credit_card_name
|
|
58
|
+
currency_code
|
|
59
|
+
error_message
|
|
60
|
+
external_payment_name
|
|
61
|
+
failed_at
|
|
62
|
+
failed_date
|
|
63
|
+
franchise_id
|
|
64
|
+
invoice_autobill
|
|
65
|
+
invoice_due_date
|
|
66
|
+
invoice_id
|
|
67
|
+
invoice_number
|
|
68
|
+
invoice_payer_email
|
|
69
|
+
invoice_payer_home_location
|
|
70
|
+
invoice_payer_id
|
|
71
|
+
invoice_payer_name
|
|
72
|
+
invoice_payer_phone
|
|
73
|
+
invoice_payer_primary_staff_name_at_sale
|
|
74
|
+
invoice_state
|
|
75
|
+
key
|
|
76
|
+
net_paid_amount
|
|
77
|
+
net_paid_revenue_amount
|
|
78
|
+
net_paid_tax_amount
|
|
79
|
+
payment_method
|
|
80
|
+
payment_method_detail
|
|
81
|
+
payment_transaction_id
|
|
82
|
+
payments_amount
|
|
83
|
+
processing_method
|
|
84
|
+
processor_transaction_id
|
|
85
|
+
refunds_amount
|
|
86
|
+
sale_location_name
|
|
87
|
+
transaction_amount
|
|
88
|
+
transaction_at
|
|
89
|
+
transaction_autopay
|
|
90
|
+
transaction_date
|
|
91
|
+
transaction_id
|
|
92
|
+
transaction_state
|
|
93
|
+
transaction_type
|
|
94
|
+
voided_at
|
|
95
|
+
].freeze
|
|
96
|
+
|
|
97
|
+
# Available summary fields (when grouping)
|
|
98
|
+
SUMMARY_FIELDS = %w[
|
|
99
|
+
business_id_summary
|
|
100
|
+
business_subdomain_summary
|
|
101
|
+
failed_count
|
|
102
|
+
invoice_count
|
|
103
|
+
settled_count
|
|
104
|
+
total_count
|
|
105
|
+
total_net_ach_paid_amount
|
|
106
|
+
total_net_american_express_paid_amount
|
|
107
|
+
total_net_amex_processing_paid_amount
|
|
108
|
+
total_net_cash_paid_amount
|
|
109
|
+
total_net_check_paid_amount
|
|
110
|
+
total_net_credit_paid_amount
|
|
111
|
+
total_net_discover_paid_amount
|
|
112
|
+
total_net_external_paid_amount
|
|
113
|
+
total_net_global_pay_processing_paid_amount
|
|
114
|
+
total_net_mastercard_paid_amount
|
|
115
|
+
total_net_other_credit_card_paid_amount
|
|
116
|
+
total_net_other_processing_paid_amount
|
|
117
|
+
total_net_paid_amount
|
|
118
|
+
total_net_paid_revenue_amount
|
|
119
|
+
total_net_paid_tax_amount
|
|
120
|
+
total_net_visa_paid_amount
|
|
121
|
+
total_payments_amount
|
|
122
|
+
total_refunds_amount
|
|
123
|
+
transaction_autopay_count
|
|
124
|
+
transaction_count
|
|
125
|
+
].freeze
|
|
126
|
+
|
|
127
|
+
# Available grouping fields
|
|
128
|
+
GROUPINGS = %w[
|
|
129
|
+
business_id
|
|
130
|
+
business_name
|
|
131
|
+
business_subdomain
|
|
132
|
+
commission_recipient_name
|
|
133
|
+
created_by_name
|
|
134
|
+
credit_card_name
|
|
135
|
+
external_payment_name
|
|
136
|
+
failed_date
|
|
137
|
+
failed_month_start_date
|
|
138
|
+
failed_quarter_start_date
|
|
139
|
+
failed_week_mon_start_date
|
|
140
|
+
failed_week_sun_start_date
|
|
141
|
+
failed_year_start_date
|
|
142
|
+
invoice_autobill
|
|
143
|
+
invoice_due_date
|
|
144
|
+
invoice_id
|
|
145
|
+
invoice_number
|
|
146
|
+
invoice_payer_home_location
|
|
147
|
+
invoice_payer_id
|
|
148
|
+
invoice_payer_name
|
|
149
|
+
invoice_payer_primary_staff_name_at_sale
|
|
150
|
+
invoice_state
|
|
151
|
+
payment_method
|
|
152
|
+
processing_method
|
|
153
|
+
sale_location_name
|
|
154
|
+
transaction_autopay
|
|
155
|
+
transaction_date
|
|
156
|
+
transaction_month_start_date
|
|
157
|
+
transaction_quarter_start_date
|
|
158
|
+
transaction_state
|
|
159
|
+
transaction_type
|
|
160
|
+
transaction_week_mon_start_date
|
|
161
|
+
transaction_week_sun_start_date
|
|
162
|
+
transaction_year_start_date
|
|
163
|
+
].freeze
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
data/lib/pike13/http_client.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "httparty"
|
|
4
|
+
require "json"
|
|
4
5
|
|
|
5
6
|
module Pike13
|
|
6
7
|
# HTTParty-based HTTP client for Pike13 API
|
|
@@ -162,9 +163,11 @@ module Pike13
|
|
|
162
163
|
return nil if response.body.nil? || response.body.empty?
|
|
163
164
|
|
|
164
165
|
parsed = response.parsed_response
|
|
166
|
+
|
|
167
|
+
# If parsed response is not a Hash (e.g., it's an Array), return as-is
|
|
165
168
|
return parsed unless parsed.is_a?(Hash)
|
|
166
169
|
|
|
167
|
-
# Handle different response formats
|
|
170
|
+
# Handle different response formats for Hash responses
|
|
168
171
|
if parsed.key?("data")
|
|
169
172
|
parsed["data"]
|
|
170
173
|
else
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "httparty"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module Pike13
|
|
7
|
+
# HTTParty-based HTTP client for Pike13 v3 Reporting API
|
|
8
|
+
# V3 API uses JSON API 1.0 (application/vnd.api+json) and a different URL structure than v2
|
|
9
|
+
class HTTPClientV3
|
|
10
|
+
include HTTParty
|
|
11
|
+
|
|
12
|
+
attr_reader :base_url, :access_token
|
|
13
|
+
|
|
14
|
+
def initialize(base_url:, access_token:)
|
|
15
|
+
@base_url = base_url
|
|
16
|
+
@access_token = access_token
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# POST request for v3 reporting queries
|
|
20
|
+
#
|
|
21
|
+
# @param path [String] The API endpoint path
|
|
22
|
+
# @param body [Hash] Request body
|
|
23
|
+
# @param params [Hash] Query parameters
|
|
24
|
+
# @return [Hash] Parsed response body
|
|
25
|
+
def post(path, body = {}, params = {})
|
|
26
|
+
handle_response do
|
|
27
|
+
self.class.post(
|
|
28
|
+
full_path(path),
|
|
29
|
+
body: body.to_json,
|
|
30
|
+
query: params,
|
|
31
|
+
headers: headers,
|
|
32
|
+
timeout: 30
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# V3 API uses /desk/api/v3/reports/... structure instead of /api/v2/desk/...
|
|
40
|
+
def full_path(path)
|
|
41
|
+
"#{base_url}/#{path}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def headers
|
|
45
|
+
{
|
|
46
|
+
"Authorization" => "Bearer #{access_token}",
|
|
47
|
+
"Content-Type" => "application/vnd.api+json",
|
|
48
|
+
"Accept" => "application/vnd.api+json"
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def handle_response
|
|
53
|
+
response = yield
|
|
54
|
+
handle_status_code(response)
|
|
55
|
+
rescue HTTParty::Error => e
|
|
56
|
+
raise Pike13::ConnectionError, "Connection failed: #{e.message}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def handle_status_code(response)
|
|
60
|
+
return parse_response_body(response) if response.code.between?(200, 299)
|
|
61
|
+
|
|
62
|
+
raise_error_for_status(response)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def raise_error_for_status(response)
|
|
66
|
+
case response.code
|
|
67
|
+
when 400 then raise Pike13::BadRequestError.new(response.body, http_status: response.code)
|
|
68
|
+
when 401 then raise Pike13::UnauthorizedError.new("Unauthorized", http_status: response.code)
|
|
69
|
+
when 404 then raise Pike13::NotFoundError.new("Resource not found", http_status: response.code)
|
|
70
|
+
when 422 then raise_validation_error(response)
|
|
71
|
+
when 429 then raise Pike13::RateLimitError.new("Rate limit exceeded", http_status: response.code)
|
|
72
|
+
when 500..599 then raise Pike13::ServerError.new("Server error", http_status: response.code)
|
|
73
|
+
else raise Pike13::APIError.new("Unexpected error", http_status: response.code)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def raise_validation_error(response)
|
|
78
|
+
parsed = parse_json_safely(response.body)
|
|
79
|
+
error_message = extract_error_message(parsed, response.body)
|
|
80
|
+
raise Pike13::ValidationError.new(error_message, http_status: response.code)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def parse_json_safely(body)
|
|
84
|
+
JSON.parse(body)
|
|
85
|
+
rescue StandardError
|
|
86
|
+
{}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def extract_error_message(parsed, fallback)
|
|
90
|
+
return fallback unless parsed.is_a?(Hash) && parsed["errors"]
|
|
91
|
+
|
|
92
|
+
parsed["errors"].is_a?(Array) ? parsed["errors"].first : parsed["errors"]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def parse_response_body(response)
|
|
96
|
+
return nil if response.body.nil? || response.body.empty?
|
|
97
|
+
|
|
98
|
+
response.parsed_response
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|