booker_ruby 1.0.1
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 +7 -0
- data/lib/booker/booker.rb +5 -0
- data/lib/booker/business_client.rb +32 -0
- data/lib/booker/business_rest.rb +89 -0
- data/lib/booker/client.rb +182 -0
- data/lib/booker/common_rest.rb +38 -0
- data/lib/booker/customer_client.rb +31 -0
- data/lib/booker/customer_rest.rb +43 -0
- data/lib/booker/errors.rb +19 -0
- data/lib/booker/generic_token_store.rb +25 -0
- data/lib/booker/models/address.rb +12 -0
- data/lib/booker/models/appointment.rb +77 -0
- data/lib/booker/models/appointment_treatment.rb +51 -0
- data/lib/booker/models/available_time.rb +13 -0
- data/lib/booker/models/business_type.rb +5 -0
- data/lib/booker/models/category.rb +5 -0
- data/lib/booker/models/class_instance.rb +25 -0
- data/lib/booker/models/country.rb +5 -0
- data/lib/booker/models/current_price.rb +5 -0
- data/lib/booker/models/customer.rb +51 -0
- data/lib/booker/models/customer_2.rb +5 -0
- data/lib/booker/models/customer_record_type.rb +5 -0
- data/lib/booker/models/discount.rb +5 -0
- data/lib/booker/models/dynamic_price.rb +11 -0
- data/lib/booker/models/employee.rb +10 -0
- data/lib/booker/models/final_total.rb +5 -0
- data/lib/booker/models/gender.rb +5 -0
- data/lib/booker/models/location.rb +18 -0
- data/lib/booker/models/model.rb +123 -0
- data/lib/booker/models/online_booking_settings.rb +23 -0
- data/lib/booker/models/original_price.rb +5 -0
- data/lib/booker/models/payment_method.rb +5 -0
- data/lib/booker/models/preferred_staff_gender.rb +5 -0
- data/lib/booker/models/price.rb +8 -0
- data/lib/booker/models/receipt_display_price.rb +5 -0
- data/lib/booker/models/room.rb +12 -0
- data/lib/booker/models/shipping_address.rb +5 -0
- data/lib/booker/models/source.rb +5 -0
- data/lib/booker/models/spa.rb +5 -0
- data/lib/booker/models/spa_employee_availability_search_item.rb +11 -0
- data/lib/booker/models/status.rb +5 -0
- data/lib/booker/models/sub_category.rb +5 -0
- data/lib/booker/models/tag_price.rb +5 -0
- data/lib/booker/models/teacher.rb +5 -0
- data/lib/booker/models/teacher_2.rb +5 -0
- data/lib/booker/models/time_zone.rb +8 -0
- data/lib/booker/models/treatment.rb +19 -0
- data/lib/booker/models/type.rb +8 -0
- data/lib/booker/models/user.rb +73 -0
- data/lib/booker/version.rb +3 -0
- data/lib/booker_ruby.rb +86 -0
- metadata +192 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module Booker
|
2
|
+
class GenericTokenStore
|
3
|
+
def self.temp_access_token
|
4
|
+
@temp_access_token
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.temp_access_token=(token)
|
8
|
+
@temp_access_token = token
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.temp_access_token_expires_at
|
12
|
+
@temp_access_token_expires_at
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.temp_access_token_expires_at=(expires_at)
|
16
|
+
@temp_access_token_expires_at = expires_at
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.update_booker_access_token!(token, expires_at)
|
20
|
+
self.temp_access_token = token
|
21
|
+
self.temp_access_token_expires_at = expires_at
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class Appointment < Model
|
4
|
+
attr_accessor 'BookingNumber',
|
5
|
+
'Confirmable',
|
6
|
+
'EndDateTime',
|
7
|
+
'FinalTotal',
|
8
|
+
'ID',
|
9
|
+
'IsCancelled',
|
10
|
+
'IsNoShow',
|
11
|
+
'LocationID',
|
12
|
+
'StartDateTime',
|
13
|
+
'Status',
|
14
|
+
'CanTakePayment',
|
15
|
+
'DateCreated',
|
16
|
+
'BelongsToEnrollment',
|
17
|
+
'Address',
|
18
|
+
'AddressID',
|
19
|
+
'AllowAutoPay',
|
20
|
+
'AppointmentTreatments',
|
21
|
+
'BelongsToGroup',
|
22
|
+
'BelongsToGroupAndGroupOrder',
|
23
|
+
'BelongsToOrder',
|
24
|
+
'CanCancel',
|
25
|
+
'CanCheckin',
|
26
|
+
'CanHaveCustomer2',
|
27
|
+
'CanRevertNoShow',
|
28
|
+
'CanUndoCheckin',
|
29
|
+
'CancellationID',
|
30
|
+
'Customer',
|
31
|
+
'Customer2',
|
32
|
+
'Customer2ID',
|
33
|
+
'CustomerID',
|
34
|
+
'CustomerLastName',
|
35
|
+
'CustomerMobilePhone',
|
36
|
+
'CustomerWorkPhone',
|
37
|
+
'DateBooked',
|
38
|
+
'DateNoShow',
|
39
|
+
'Employee',
|
40
|
+
'EmployeeFirstName',
|
41
|
+
'EmployeeLastName',
|
42
|
+
'GroupID',
|
43
|
+
'GroupName',
|
44
|
+
'GroupNumber',
|
45
|
+
'GroupTypeID',
|
46
|
+
'IsCancelledOrNoShow',
|
47
|
+
'IsCheckedInInService',
|
48
|
+
'IsPartOfClassPackageBooking',
|
49
|
+
'IsPreBookedAtPastCheckout',
|
50
|
+
'IsRecurring',
|
51
|
+
'IsWebBooking',
|
52
|
+
'Notes',
|
53
|
+
'OrderID',
|
54
|
+
'OrderStatusID',
|
55
|
+
'PackageID',
|
56
|
+
'PaymentID',
|
57
|
+
'PaymentItemID',
|
58
|
+
'PrimaryAppointmentTreatmentID',
|
59
|
+
'RecurrenceID',
|
60
|
+
'Room',
|
61
|
+
'Source',
|
62
|
+
'Treatment',
|
63
|
+
'TreatmentName',
|
64
|
+
'Type',
|
65
|
+
'IsHeld',
|
66
|
+
'HoldForMinutes',
|
67
|
+
'HeldSince',
|
68
|
+
'IsServiceComplete',
|
69
|
+
'IsCheckout',
|
70
|
+
'DateCheckIn',
|
71
|
+
'IsFromWaitList',
|
72
|
+
'IsFromClassWaitList',
|
73
|
+
'CustomerRecordTypeID',
|
74
|
+
'CustomerParentID'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class AppointmentTreatment < Model
|
4
|
+
attr_accessor 'AppointmentID',
|
5
|
+
'DynamicPrice',
|
6
|
+
'EndDateTime',
|
7
|
+
'ID',
|
8
|
+
'StartDateTime',
|
9
|
+
'ChildID',
|
10
|
+
'ChildName',
|
11
|
+
'AllowChangeStartTime',
|
12
|
+
'DynamicPriceID',
|
13
|
+
'Employee',
|
14
|
+
'Employee2FullName',
|
15
|
+
'Employee2ID',
|
16
|
+
'EmployeeFirstName',
|
17
|
+
'EmployeeFullName',
|
18
|
+
'EmployeeID',
|
19
|
+
'EmployeeLastName',
|
20
|
+
'EmployeeRecoveryDuration',
|
21
|
+
'EmployeeTypeID',
|
22
|
+
'EmployeeWasRequested',
|
23
|
+
'FinishStartDateTime',
|
24
|
+
'FinishTimeAppliedToEmployee',
|
25
|
+
'FinishTimeAppliedToRoom',
|
26
|
+
'FinishTimeDuration',
|
27
|
+
'FinishTimeOriginalDuration',
|
28
|
+
'ProcessingStartDateTime',
|
29
|
+
'ProcessingTimeAppliedToRoom',
|
30
|
+
'ProcessingTimeAppliedToEmployee',
|
31
|
+
'ProcessingTimeDuration',
|
32
|
+
'ProcessingTimeOriginalDuration',
|
33
|
+
'RequiresProcessingTime',
|
34
|
+
'Room',
|
35
|
+
'RoomID',
|
36
|
+
'RoomName',
|
37
|
+
'RoomRecoveryDuration',
|
38
|
+
'StartTimeDuration',
|
39
|
+
'StartTimeOriginalDuration',
|
40
|
+
'TagPrice',
|
41
|
+
'Treatment',
|
42
|
+
'TreatmentDuration',
|
43
|
+
'TreatmentID',
|
44
|
+
'TreatmentIsForCouples',
|
45
|
+
'TreatmentName',
|
46
|
+
'ClassInstanceID',
|
47
|
+
'IsDurationOverridden'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class ClassInstance < Model
|
4
|
+
attr_accessor 'ID',
|
5
|
+
'EndDateTime',
|
6
|
+
'HasClassFilled',
|
7
|
+
'IsForMembersOnly',
|
8
|
+
'IsRecurring',
|
9
|
+
'IsSpecialEvent',
|
10
|
+
'IsWorkshop',
|
11
|
+
'NumReserved',
|
12
|
+
'Price',
|
13
|
+
'RoomName',
|
14
|
+
'StartDateTime',
|
15
|
+
'Teacher',
|
16
|
+
'Teacher2',
|
17
|
+
'TotalCapacity',
|
18
|
+
'TreatmentDuration',
|
19
|
+
'ListAsSubstitute',
|
20
|
+
'IsEnrollable',
|
21
|
+
'SeriesID',
|
22
|
+
'Treatment'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class Customer < Model
|
4
|
+
attr_accessor 'CustomerID',
|
5
|
+
'GUID',
|
6
|
+
'Address',
|
7
|
+
'AllowReceiveEmails',
|
8
|
+
'AllowReceiveSMS',
|
9
|
+
'SendEmail',
|
10
|
+
'CellPhone',
|
11
|
+
'CreditCard',
|
12
|
+
'Email',
|
13
|
+
'FirstName',
|
14
|
+
'HasActiveMembership',
|
15
|
+
'HomePhone',
|
16
|
+
'MobilePhone',
|
17
|
+
'LastName',
|
18
|
+
'WorkPhone',
|
19
|
+
'WorkPhoneExt',
|
20
|
+
'ShippingAddress',
|
21
|
+
'CustomerRecordType',
|
22
|
+
'DateOfBirth',
|
23
|
+
'Gender',
|
24
|
+
'GenderID',
|
25
|
+
'HasMembership',
|
26
|
+
'HasPastMembership',
|
27
|
+
'IsNewCustomer',
|
28
|
+
'LoyaltyPoints',
|
29
|
+
'LocationID',
|
30
|
+
'LocationName',
|
31
|
+
'NumberOfReferrals',
|
32
|
+
'PreferredStaffGender',
|
33
|
+
'EmergencyContactName',
|
34
|
+
'EmergencyContactPhone',
|
35
|
+
'EmergencyContactRelationship',
|
36
|
+
'IsActive',
|
37
|
+
'Occupation',
|
38
|
+
'PreferredStaffMemberID',
|
39
|
+
'ReferredByCustomerID'
|
40
|
+
|
41
|
+
def self.from_list(array)
|
42
|
+
if array.any? && array.first['Customer']
|
43
|
+
flattened = array.map{|a| a['Customer'].merge('CustomerID' => a['CustomerID'])}
|
44
|
+
super(flattened)
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class Location < Model
|
4
|
+
attr_accessor 'ID',
|
5
|
+
'AccountName',
|
6
|
+
'BusinessName',
|
7
|
+
'BusinessType',
|
8
|
+
'EmailAddress',
|
9
|
+
'Address',
|
10
|
+
'Phone',
|
11
|
+
'TimeZone',
|
12
|
+
'WebSite',
|
13
|
+
'IsDistributionPartner',
|
14
|
+
'EncryptedLocationID',
|
15
|
+
'BrandAccountName'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Booker
|
2
|
+
module Models
|
3
|
+
class Model
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
options.each do |key, value|
|
7
|
+
send(:"#{key}=", value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_hash
|
12
|
+
hash = {}
|
13
|
+
self.instance_variables.each do |var|
|
14
|
+
value = self.instance_variable_get var
|
15
|
+
if value.is_a? Array
|
16
|
+
new_value = hash_list(value)
|
17
|
+
elsif value.is_a? Booker::Models::Model
|
18
|
+
new_value = value.to_hash
|
19
|
+
elsif value.is_a? Time
|
20
|
+
new_value = self.class.time_to_booker_datetime(value)
|
21
|
+
elsif value.is_a? Date
|
22
|
+
time = value.in_time_zone
|
23
|
+
new_value = self.class.time_to_booker_datetime(time)
|
24
|
+
else
|
25
|
+
new_value = value
|
26
|
+
end
|
27
|
+
hash[var[1..-1]] = new_value
|
28
|
+
end
|
29
|
+
hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
Oj.dump(to_hash, mode: :compat)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.from_hash(hash)
|
37
|
+
model = self.new
|
38
|
+
hash.each do |key, value|
|
39
|
+
if model.respond_to?(:"#{key}")
|
40
|
+
constantized = self.constantize(key)
|
41
|
+
if constantized
|
42
|
+
if value.is_a?(Array) && value.first.is_a?(Hash)
|
43
|
+
model.send(:"#{key}=", constantized.from_list(value))
|
44
|
+
next
|
45
|
+
elsif value.is_a? Hash
|
46
|
+
model.send(:"#{key}=", constantized.from_hash(value))
|
47
|
+
next
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if value.is_a?(String) && value.start_with?('/Date(')
|
52
|
+
model.send(:"#{key}=", time_from_booker_datetime(value))
|
53
|
+
elsif !value.nil?
|
54
|
+
model.send(:"#{key}=", value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
model
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.from_list(array)
|
62
|
+
array.map{|item| self.from_hash(item)}
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.constantize(key)
|
66
|
+
begin
|
67
|
+
Booker::Models.const_get("Booker::Models::#{key.singularize}")
|
68
|
+
rescue NameError
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Booker's API hands you back all time as if the business is in server time.
|
74
|
+
# First load the time in server time, then return the same hours and minutes in current time zone.
|
75
|
+
# Booker will hopefully fix this in a future API version. Sorry.
|
76
|
+
def self.time_from_booker_datetime(booker_datetime)
|
77
|
+
timestamp = booker_datetime[/\/Date\((.\d+)[\-\+]/, 1].to_i / 1000.to_f
|
78
|
+
|
79
|
+
original_tz = Time.zone
|
80
|
+
begin
|
81
|
+
# Booker's server is always EST
|
82
|
+
Time.zone = Booker::Client::TimeZone
|
83
|
+
|
84
|
+
booker_time = Time.zone.at(timestamp)
|
85
|
+
ensure
|
86
|
+
Time.zone = original_tz
|
87
|
+
end
|
88
|
+
|
89
|
+
# Convert it back to location time without changing hours and minutes
|
90
|
+
Time.zone.parse(booker_time.strftime('%Y-%m-%d %H:%M:%S'))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Booker's API requires times to be sent in as if the business is in Eastern Time!
|
94
|
+
def self.time_to_booker_datetime(time)
|
95
|
+
original_tz = Time.zone
|
96
|
+
|
97
|
+
begin
|
98
|
+
# Booker's server is always EST
|
99
|
+
Time.zone = Booker::Client::TimeZone
|
100
|
+
timestamp = (Time.zone.parse(time.strftime("%Y-%m-%dT%H:%M:%S")).to_f * 1000).to_i
|
101
|
+
ensure
|
102
|
+
Time.zone = original_tz
|
103
|
+
end
|
104
|
+
|
105
|
+
"/Date(#{timestamp})/"
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def hash_list(array)
|
111
|
+
array.map do |item|
|
112
|
+
if item.is_a? Array
|
113
|
+
hash_list(item)
|
114
|
+
elsif item.is_a? Booker::Models::Model
|
115
|
+
item.to_hash
|
116
|
+
else
|
117
|
+
item
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|