booker_ruby 1.14.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/lib/booker/client.rb +154 -49
  3. data/lib/booker/errors.rb +6 -2
  4. data/lib/booker/model.rb +84 -0
  5. data/lib/booker/v4.1/availability.rb +21 -0
  6. data/lib/booker/v4.1/booking.rb +87 -0
  7. data/lib/booker/v4.1/merchant.rb +55 -0
  8. data/lib/booker/v4/business_client.rb +9 -0
  9. data/lib/booker/v4/business_rest.rb +88 -0
  10. data/lib/booker/v4/common_rest.rb +21 -0
  11. data/lib/booker/v4/customer_client.rb +15 -0
  12. data/lib/booker/v4/customer_rest.rb +15 -0
  13. data/lib/booker/v4/models/address.rb +14 -0
  14. data/lib/booker/v4/models/appointment.rb +79 -0
  15. data/lib/booker/v4/models/appointment_treatment.rb +53 -0
  16. data/lib/booker/v4/models/available_time.rb +15 -0
  17. data/lib/booker/v4/models/business_type.rb +7 -0
  18. data/lib/booker/v4/models/category.rb +7 -0
  19. data/lib/booker/v4/models/class_instance.rb +27 -0
  20. data/lib/booker/v4/models/country.rb +21 -0
  21. data/lib/booker/v4/models/current_price.rb +7 -0
  22. data/lib/booker/v4/models/customer.rb +54 -0
  23. data/lib/booker/v4/models/customer_2.rb +7 -0
  24. data/lib/booker/v4/models/customer_record_type.rb +7 -0
  25. data/lib/booker/v4/models/discount.rb +7 -0
  26. data/lib/booker/v4/models/dynamic_price.rb +13 -0
  27. data/lib/booker/v4/models/employee.rb +12 -0
  28. data/lib/booker/v4/models/feature_settings.rb +9 -0
  29. data/lib/booker/v4/models/final_total.rb +7 -0
  30. data/lib/booker/v4/models/gender.rb +7 -0
  31. data/lib/booker/v4/models/itinerary_time_slot.rb +9 -0
  32. data/lib/booker/v4/models/itinerary_time_slots_list.rb +9 -0
  33. data/lib/booker/v4/models/location.rb +40 -0
  34. data/lib/booker/v4/models/location_day_schedule.rb +20 -0
  35. data/lib/booker/v4/models/model.rb +78 -0
  36. data/lib/booker/v4/models/multi_service_availability_result.rb +9 -0
  37. data/lib/booker/v4/models/notification_settings.rb +14 -0
  38. data/lib/booker/v4/models/online_booking_settings.rb +25 -0
  39. data/lib/booker/v4/models/original_price.rb +7 -0
  40. data/lib/booker/v4/models/payment_method.rb +7 -0
  41. data/lib/booker/v4/models/preferred_staff_gender.rb +7 -0
  42. data/lib/booker/v4/models/price.rb +10 -0
  43. data/lib/booker/v4/models/receipt_display_price.rb +7 -0
  44. data/lib/booker/v4/models/room.rb +14 -0
  45. data/lib/booker/v4/models/shipping_address.rb +7 -0
  46. data/lib/booker/v4/models/source.rb +7 -0
  47. data/lib/booker/v4/models/spa.rb +7 -0
  48. data/lib/booker/v4/models/spa_employee_availability_search_item.rb +13 -0
  49. data/lib/booker/v4/models/status.rb +7 -0
  50. data/lib/booker/v4/models/sub_category.rb +7 -0
  51. data/lib/booker/v4/models/tag_price.rb +7 -0
  52. data/lib/booker/v4/models/teacher.rb +7 -0
  53. data/lib/booker/v4/models/teacher_2.rb +7 -0
  54. data/lib/booker/v4/models/time_zone.rb +10 -0
  55. data/lib/booker/v4/models/treatment.rb +21 -0
  56. data/lib/booker/v4/models/treatment_time_slot.rb +7 -0
  57. data/lib/booker/v4/models/type.rb +10 -0
  58. data/lib/booker/v4/models/user.rb +75 -0
  59. data/lib/booker/v4/request_helper.rb +33 -0
  60. data/lib/booker/v5/availability.rb +45 -0
  61. data/lib/booker/v5/models/availability.rb +18 -0
  62. data/lib/booker/v5/models/availability_result.rb +12 -0
  63. data/lib/booker/v5/models/location_hour.rb +16 -0
  64. data/lib/booker/v5/models/model.rb +9 -0
  65. data/lib/booker/v5/models/service.rb +13 -0
  66. data/lib/booker/v5/models/service_category.rb +11 -0
  67. data/lib/booker/version.rb +1 -1
  68. data/lib/booker_ruby.rb +70 -52
  69. metadata +80 -54
  70. data/lib/booker/business_client.rb +0 -22
  71. data/lib/booker/business_rest.rb +0 -112
  72. data/lib/booker/common_rest.rb +0 -43
  73. data/lib/booker/customer_client.rb +0 -17
  74. data/lib/booker/customer_rest.rb +0 -53
  75. data/lib/booker/models/address.rb +0 -12
  76. data/lib/booker/models/appointment.rb +0 -77
  77. data/lib/booker/models/appointment_treatment.rb +0 -51
  78. data/lib/booker/models/available_time.rb +0 -13
  79. data/lib/booker/models/business_type.rb +0 -5
  80. data/lib/booker/models/category.rb +0 -5
  81. data/lib/booker/models/class_instance.rb +0 -25
  82. data/lib/booker/models/country.rb +0 -19
  83. data/lib/booker/models/current_price.rb +0 -5
  84. data/lib/booker/models/customer.rb +0 -52
  85. data/lib/booker/models/customer_2.rb +0 -5
  86. data/lib/booker/models/customer_record_type.rb +0 -5
  87. data/lib/booker/models/discount.rb +0 -5
  88. data/lib/booker/models/dynamic_price.rb +0 -11
  89. data/lib/booker/models/employee.rb +0 -10
  90. data/lib/booker/models/feature_settings.rb +0 -7
  91. data/lib/booker/models/final_total.rb +0 -5
  92. data/lib/booker/models/gender.rb +0 -5
  93. data/lib/booker/models/itinerary_time_slot.rb +0 -7
  94. data/lib/booker/models/itinerary_time_slots_list.rb +0 -7
  95. data/lib/booker/models/location.rb +0 -38
  96. data/lib/booker/models/location_day_schedule.rb +0 -18
  97. data/lib/booker/models/model.rb +0 -150
  98. data/lib/booker/models/multi_service_availability_result.rb +0 -7
  99. data/lib/booker/models/notification_settings.rb +0 -12
  100. data/lib/booker/models/online_booking_settings.rb +0 -23
  101. data/lib/booker/models/original_price.rb +0 -5
  102. data/lib/booker/models/payment_method.rb +0 -5
  103. data/lib/booker/models/preferred_staff_gender.rb +0 -5
  104. data/lib/booker/models/price.rb +0 -8
  105. data/lib/booker/models/receipt_display_price.rb +0 -5
  106. data/lib/booker/models/room.rb +0 -12
  107. data/lib/booker/models/shipping_address.rb +0 -5
  108. data/lib/booker/models/source.rb +0 -5
  109. data/lib/booker/models/spa.rb +0 -5
  110. data/lib/booker/models/spa_employee_availability_search_item.rb +0 -11
  111. data/lib/booker/models/status.rb +0 -5
  112. data/lib/booker/models/sub_category.rb +0 -5
  113. data/lib/booker/models/tag_price.rb +0 -5
  114. data/lib/booker/models/teacher.rb +0 -5
  115. data/lib/booker/models/teacher_2.rb +0 -5
  116. data/lib/booker/models/time_zone.rb +0 -8
  117. data/lib/booker/models/treatment.rb +0 -19
  118. data/lib/booker/models/treatment_time_slot.rb +0 -5
  119. data/lib/booker/models/type.rb +0 -8
  120. data/lib/booker/models/user.rb +0 -73
@@ -1,51 +0,0 @@
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
-
@@ -1,13 +0,0 @@
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
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class BusinessType < Type; end
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class Category < Type; end
4
- end
5
- end
@@ -1,25 +0,0 @@
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
@@ -1,19 +0,0 @@
1
- module Booker
2
- module Models
3
- class Country < Type
4
- # ISO 3166-1 alpha-2 Codes
5
- IDS_TO_ISO_CODES = YAML::load_file(File.join(__dir__, '..', 'config', 'booker_country_ids_to_iso_codes.yml')).freeze
6
-
7
- def country_code; IDS_TO_ISO_CODES[self.ID]; end
8
-
9
- def self.from_country_code(code)
10
- country = self.new ID: IDS_TO_ISO_CODES.detect{|k, v| v == code}.try(:[], 0)
11
- if country.ID.nil?
12
- raise ArgumentError, 'Country code not recognized'
13
- else
14
- country
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class CurrentPrice < Price; end
4
- end
5
- end
@@ -1,52 +0,0 @@
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', # Returned when using FindCustomers
11
- 'CreditCard',
12
- 'Email',
13
- 'FirstName',
14
- 'HasActiveMembership',
15
- 'HomePhone',
16
- 'MobilePhone', # Set this when making an appointment
17
- 'MobilePhoneCarrierID',
18
- 'LastName',
19
- 'WorkPhone',
20
- 'WorkPhoneExt',
21
- 'ShippingAddress',
22
- 'CustomerRecordType',
23
- 'DateOfBirth',
24
- 'Gender',
25
- 'GenderID',
26
- 'HasMembership',
27
- 'HasPastMembership',
28
- 'IsNewCustomer',
29
- 'LoyaltyPoints',
30
- 'LocationID',
31
- 'LocationName',
32
- 'NumberOfReferrals',
33
- 'PreferredStaffGender',
34
- 'EmergencyContactName',
35
- 'EmergencyContactPhone',
36
- 'EmergencyContactRelationship',
37
- 'IsActive',
38
- 'Occupation',
39
- 'PreferredStaffMemberID',
40
- 'ReferredByCustomerID'
41
-
42
- def self.from_list(array)
43
- if array.any? && array.first['Customer']
44
- flattened = array.map{|a| a['Customer'].merge('CustomerID' => a['CustomerID'])}
45
- super(flattened)
46
- else
47
- super
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class Customer2 < Customer; end
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class CustomerRecordType < Type; end
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class Discount < Price; end
4
- end
5
- end
@@ -1,11 +0,0 @@
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
@@ -1,10 +0,0 @@
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
@@ -1,7 +0,0 @@
1
- module Booker
2
- module Models
3
- class FeatureSettings < Model
4
- attr_accessor 'UseFrederick', 'UsePromote'
5
- end
6
- end
7
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class FinalTotal < Price; end
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module Booker
2
- module Models
3
- class Gender < Type; end
4
- end
5
- end
@@ -1,7 +0,0 @@
1
- module Booker
2
- module Models
3
- class ItineraryTimeSlot < Model
4
- attr_accessor 'TreatmentTimeSlots'
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Booker
2
- module Models
3
- class ItineraryTimeSlotsList < Model
4
- attr_accessor 'ItineraryTimeSlots'
5
- end
6
- end
7
- end
@@ -1,38 +0,0 @@
1
- module Booker
2
- module Models
3
- class Location < Model
4
- ACCOUNT_STATUSES = [
5
- nil,
6
- 'Implementation',
7
- 'Demo',
8
- 'LiveNoCharge',
9
- 'Live',
10
- 'Terminated',
11
- 'ChargeNotLive'
12
- ].map(&:freeze).freeze
13
-
14
- attr_accessor 'ID',
15
- 'AccountName',
16
- 'BusinessName',
17
- 'BusinessType',
18
- 'EmailAddress',
19
- 'Address',
20
- 'Phone',
21
- 'TimeZone',
22
- 'WebSite',
23
- 'IsDistributionPartner',
24
- 'EncryptedLocationID',
25
- 'BrandAccountName',
26
- 'LogoUrl',
27
- 'BusinessType',
28
- 'FirstName',
29
- 'LastName',
30
- 'CurrencyCode',
31
- 'Status'
32
-
33
- def status_name
34
- self.Status ? ACCOUNT_STATUSES[self.Status] : nil
35
- end
36
- end
37
- end
38
- end
@@ -1,18 +0,0 @@
1
- module Booker
2
- module Models
3
- class LocationDaySchedule < Model
4
- attr_accessor 'Weekday',
5
- 'StartTime',
6
- 'EndTime'
7
-
8
- def self.from_hash(hash)
9
- model = super
10
- model.Weekday = to_wday(model.Weekday)
11
- strftime_format = '%T'
12
- model.StartTime = model.StartTime.try(:strftime, strftime_format)
13
- model.EndTime = model.EndTime.try(:strftime, strftime_format)
14
- model
15
- end
16
- end
17
- end
18
- end
@@ -1,150 +0,0 @@
1
- module Booker
2
- module Models
3
- class Model
4
- def initialize(options = {})
5
- options.each { |key, value| send(:"#{key}=", value) }
6
- end
7
-
8
- def to_hash
9
- hash = {}
10
- self.instance_variables.each do |var|
11
- value = self.instance_variable_get var
12
- if value.is_a? Array
13
- new_value = hash_list(value)
14
- elsif value.is_a? Booker::Models::Model
15
- new_value = value.to_hash
16
- elsif value.is_a? Time
17
- new_value = self.class.time_to_booker_datetime(value)
18
- elsif value.is_a? Date
19
- time = value.in_time_zone
20
- new_value = self.class.time_to_booker_datetime(time)
21
- else
22
- new_value = value
23
- end
24
- hash[var[1..-1]] = new_value
25
- end
26
- hash
27
- end
28
-
29
- def to_json; Oj.dump(to_hash, mode: :compat); end
30
-
31
- def self.from_hash(hash)
32
- model = self.new
33
- hash.each do |key, value|
34
- if model.respond_to?(:"#{key}")
35
- constantized = self.constantize(key)
36
- if constantized
37
- if value.is_a?(Array) && value.first.is_a?(Hash)
38
- model.send(:"#{key}=", constantized.from_list(value))
39
- next
40
- elsif value.is_a? Hash
41
- model.send(:"#{key}=", constantized.from_hash(value))
42
- next
43
- end
44
- end
45
-
46
- if value.is_a?(String) && value.start_with?('/Date(')
47
- model.send(:"#{key}=", time_from_booker_datetime(value))
48
- elsif !value.nil?
49
- model.send(:"#{key}=", value)
50
- end
51
- end
52
- end
53
- model
54
- end
55
-
56
- def self.from_list(array); array.map { |item| self.from_hash(item) }; end
57
-
58
- def self.constantize(key)
59
- begin
60
- Booker::Models.const_get("Booker::Models::#{key.singularize}")
61
- rescue NameError
62
- nil
63
- end
64
- end
65
-
66
- # Booker's API hands you back all time as if the business is in server time.
67
- # First load the time in server time, then return the same hours and minutes in current time zone.
68
- # Booker will hopefully fix this in a future API version. Sorry.
69
- def self.time_from_booker_datetime(booker_datetime)
70
- timestamp = booker_datetime[/\/Date\((.\d+)[\-\+]/, 1].to_i / 1000.to_f
71
-
72
- original_tz = Time.zone
73
- begin
74
- # Booker's server is always EST
75
- Time.zone = Booker::Client::TimeZone
76
-
77
- booker_time = Time.zone.at(timestamp)
78
- ensure
79
- Time.zone = original_tz
80
- end
81
-
82
- # Convert it back to location time without changing hours and minutes
83
- Time.zone.parse(booker_time.strftime('%Y-%m-%d %H:%M:%S'))
84
- end
85
-
86
- # Booker's API requires times to be sent in as if the business is in Eastern Time!
87
- def self.time_to_booker_datetime(time)
88
- original_tz = Time.zone
89
-
90
- begin
91
- # Booker's server is always EST
92
- Time.zone = Booker::Client::TimeZone
93
- timestamp = (Time.zone.parse(time.strftime("%Y-%m-%dT%H:%M:%S")).to_f * 1000).to_i
94
- ensure
95
- Time.zone = original_tz
96
- end
97
-
98
- "/Date(#{timestamp})/"
99
- end
100
-
101
- def self.timezone_from_booker_timezone(booker_timezone_name)
102
- normalized_booker_timezone_name = Booker::Helpers::ActiveSupport.to_active_support(booker_timezone_name)
103
- return normalized_booker_timezone_name if normalized_booker_timezone_name.present?
104
-
105
- begin
106
- Booker::Helpers::LoggingHelper.log_issue(
107
- 'Unable to find time zone name using Booker::Helpers::ActiveSupport.to_active_support',
108
- booker_timezone_name: booker_timezone_name
109
- )
110
- rescue
111
- end
112
-
113
- timezone_from_booker_offset!(booker_timezone_name)
114
- end
115
-
116
- def self.timezone_from_booker_offset!(booker_timezone_name)
117
- booker_offset_match = booker_timezone_name.scan(/(\A)(.*)(?=\))/).first
118
-
119
- if booker_offset_match.present?
120
- booker_offset = booker_offset_match.delete_if { |match| match.blank? }.first
121
-
122
- if booker_offset
123
- booker_timezone_map_key = Booker::Helpers::ActiveSupport.booker_timezone_names.find do |key|
124
- key.start_with?(booker_offset)
125
- end
126
-
127
- return Booker::Helpers::ActiveSupport.to_active_support(booker_timezone_map_key) if booker_timezone_map_key
128
- end
129
- end
130
-
131
- raise Booker::Error
132
- end
133
-
134
- def self.to_wday(booker_wday); Date.parse(booker_wday).wday; end
135
-
136
- private
137
- def hash_list(array)
138
- array.map do |item|
139
- if item.is_a? Array
140
- hash_list(item)
141
- elsif item.is_a? Booker::Models::Model
142
- item.to_hash
143
- else
144
- item
145
- end
146
- end
147
- end
148
- end
149
- end
150
- end