booker_ruby 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/lib/booker/booker.rb +5 -0
  3. data/lib/booker/business_client.rb +32 -0
  4. data/lib/booker/business_rest.rb +89 -0
  5. data/lib/booker/client.rb +182 -0
  6. data/lib/booker/common_rest.rb +38 -0
  7. data/lib/booker/customer_client.rb +31 -0
  8. data/lib/booker/customer_rest.rb +43 -0
  9. data/lib/booker/errors.rb +19 -0
  10. data/lib/booker/generic_token_store.rb +25 -0
  11. data/lib/booker/models/address.rb +12 -0
  12. data/lib/booker/models/appointment.rb +77 -0
  13. data/lib/booker/models/appointment_treatment.rb +51 -0
  14. data/lib/booker/models/available_time.rb +13 -0
  15. data/lib/booker/models/business_type.rb +5 -0
  16. data/lib/booker/models/category.rb +5 -0
  17. data/lib/booker/models/class_instance.rb +25 -0
  18. data/lib/booker/models/country.rb +5 -0
  19. data/lib/booker/models/current_price.rb +5 -0
  20. data/lib/booker/models/customer.rb +51 -0
  21. data/lib/booker/models/customer_2.rb +5 -0
  22. data/lib/booker/models/customer_record_type.rb +5 -0
  23. data/lib/booker/models/discount.rb +5 -0
  24. data/lib/booker/models/dynamic_price.rb +11 -0
  25. data/lib/booker/models/employee.rb +10 -0
  26. data/lib/booker/models/final_total.rb +5 -0
  27. data/lib/booker/models/gender.rb +5 -0
  28. data/lib/booker/models/location.rb +18 -0
  29. data/lib/booker/models/model.rb +123 -0
  30. data/lib/booker/models/online_booking_settings.rb +23 -0
  31. data/lib/booker/models/original_price.rb +5 -0
  32. data/lib/booker/models/payment_method.rb +5 -0
  33. data/lib/booker/models/preferred_staff_gender.rb +5 -0
  34. data/lib/booker/models/price.rb +8 -0
  35. data/lib/booker/models/receipt_display_price.rb +5 -0
  36. data/lib/booker/models/room.rb +12 -0
  37. data/lib/booker/models/shipping_address.rb +5 -0
  38. data/lib/booker/models/source.rb +5 -0
  39. data/lib/booker/models/spa.rb +5 -0
  40. data/lib/booker/models/spa_employee_availability_search_item.rb +11 -0
  41. data/lib/booker/models/status.rb +5 -0
  42. data/lib/booker/models/sub_category.rb +5 -0
  43. data/lib/booker/models/tag_price.rb +5 -0
  44. data/lib/booker/models/teacher.rb +5 -0
  45. data/lib/booker/models/teacher_2.rb +5 -0
  46. data/lib/booker/models/time_zone.rb +8 -0
  47. data/lib/booker/models/treatment.rb +19 -0
  48. data/lib/booker/models/type.rb +8 -0
  49. data/lib/booker/models/user.rb +73 -0
  50. data/lib/booker/version.rb +3 -0
  51. data/lib/booker_ruby.rb +86 -0
  52. 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,12 @@
1
+ module Booker
2
+ module Models
3
+ class Address < Model
4
+ attr_accessor 'Street1',
5
+ 'Street2',
6
+ 'City',
7
+ 'State',
8
+ 'Zip',
9
+ 'Country'
10
+ end
11
+ end
12
+ 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,13 @@
1
+ module Booker
2
+ module Models
3
+ class AvailableTime < Model
4
+ attr_accessor 'CurrentPrice',
5
+ 'Duration',
6
+ 'EmployeeID',
7
+ 'StartDateTime',
8
+ 'TreatmentID',
9
+ 'RoomID',
10
+ 'Employee2ID'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class BusinessType < Type; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class Category < Type; end
4
+ end
5
+ end
@@ -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,5 @@
1
+ module Booker
2
+ module Models
3
+ class Country < Type; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class CurrentPrice < Price; end
4
+ end
5
+ 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,5 @@
1
+ module Booker
2
+ module Models
3
+ class Customer2 < Customer; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class CustomerRecordType < Type; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class Discount < Price; end
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module Booker
2
+ module Models
3
+ class DynamicPrice < Model
4
+ attr_accessor 'Discount',
5
+ 'FinalPrice',
6
+ 'OriginalPrice',
7
+ 'ReceiptDisplayPrice',
8
+ 'OriginalTagPrice'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Booker
2
+ module Models
3
+ class Employee < Model
4
+ attr_accessor 'ID',
5
+ 'FirstName',
6
+ 'LastName',
7
+ 'Gender'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class FinalTotal < Price; end
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Booker
2
+ module Models
3
+ class Gender < Type; end
4
+ end
5
+ 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