prioticket 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a8270ce77d4f2db94fbdd7ba0393af31199f9863
4
+ data.tar.gz: 496fdc625a0d8006ed9734bed00e055d108e5028
5
+ SHA512:
6
+ metadata.gz: 55f87f2ad13a09ed5ad7f9e08636f7f7b5a7f26b4dcea6b078e4758eb16b17a0e74342a6be42670b2a2f2ea988a71d8ac6c7a004c490f5a5f35a15ec8ccd3a10
7
+ data.tar.gz: 11d934e649cb210de50288c330f7a73355400579760f1f0b2626c2592b5bab68e31a254a04175904139e41c3ffce129a0187a726bbb8ddd6e913894564acbf52
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.3
5
+ before_install: gem install bundler -v 1.13.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in prioticket.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Henk Meijer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,213 @@
1
+ # PrioTicket
2
+ [![Gem Version](https://badge.fury.io/rb/prioticket.svg)](https://badge.fury.io/rb/prioticket)
3
+ [![Dependency Status](https://gemnasium.com/henkm/prioticket.svg)](https://gemnasium.com/henkm/prioticket)
4
+ [![Code Climate](https://codeclimate.com/github/henkm/prioticket/badges/gpa.svg)](https://codeclimate.com/github/henkm/prioticket)
5
+
6
+ This gem works as a simple Ruby wrapper for the PrioTicket API. All the API functions are implemented.
7
+
8
+ Instead of working with JSON, you work with Ruby Classes and intuitive methods.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'prioticket'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install prioticket
25
+
26
+ ## Configuration
27
+
28
+ First, obtain an API key from PrioTicket. Set it up like this:
29
+ ```ruby
30
+ PrioTicket::Config.api_key = "MY-API-KEY"
31
+ PrioTicket::Config.environment = "test"
32
+ ```
33
+
34
+ To use this gem in a Rails project:
35
+ ```ruby
36
+ # config/development.rb
37
+ config.prioticcket.api_key = "MY-API-KEY"
38
+ config.prioticcket.environment = "test"
39
+ ```
40
+
41
+ ## Usage
42
+ The available classes and methods are listed below. General rule of thumb: all the naming is 100% consistant with the official API Documentation. So use `PrioTicket::Booking.new(booking_name: 'John Doe', booking_email: 'john@example.net')` instead of using the more intuitive `PrioTicket::Booking.new(name: 'John Doe', email: 'john@example.com')`
43
+
44
+ **Important**: the `Reservation` and `Booking` classes will only create a new reservation/booking in memory, when initialized (e.g. `Reservation.new(...)`). To submit it to the server, call `save`.
45
+
46
+ ### TicketList
47
+ To list the available tickets, call:
48
+ ```ruby
49
+ @ticket_list = PrioTicket::TicketList.find(distributor_id: 1234, identifier: "my-unique-order-abc-123")
50
+ # Returns an object with a method `tickets`, which returns an array of tickets:
51
+ # => <PrioTicket::TicketList @tickets=[##<PrioTicket::Ticket @ticket_id=362, @ticket_title="100 Highlights Cruise", @venue_name="Stromma Nederland", @txt_language="zh,ru,pt,nl,it,fr,de,es,en">, etc...]>
52
+ ```
53
+
54
+ ### TicketDetails
55
+ There are two ways to collect detailed information about a Ticket from the TicketList:
56
+
57
+ #### Find them using the `find` method
58
+
59
+ ```ruby
60
+ @ticket_details = PrioTicket::TicketDetails.find(distributor_id: 1234, ticket_id: 123, identifier: "my-unique-order-abc-123")
61
+ # => <PrioTicket::TicketDetails @ticket_id=1234, @ticket_title="100 Highlights Cruise", @short_description="The No.1 Amsterdam canal cruise", etc...>
62
+ ```
63
+
64
+ #### Collect them via the parent object
65
+ ```ruby
66
+ @ticket_list = PrioTicket::TicketList.find(distributor_id: 1234, identifier: "my-unique-order-abc-123")
67
+ @ticket_details = @ticket_list.first.ticket_details
68
+ # => <PrioTicket::TicketDetails @ticket_id=1234, @ticket_title="100 Highlights Cruise", @short_description="The No.1 Amsterdam canal cruise", etc...>
69
+ ```
70
+
71
+ So to get the tags from a certain TicketDetails, you can call:
72
+ ```ruby
73
+ @ticket_list.first.ticket_details.tags
74
+ # => ["Students", "Wheelchair accessible"]
75
+ ```
76
+ or:
77
+ ```ruby
78
+ @ticket_list.first.ticket_details.company_opening_times.first.start_from
79
+ # => "09:00:00"
80
+
81
+ ```
82
+
83
+ ### Availabilities
84
+ The same goes for fetching availabilities:
85
+ ```ruby
86
+ @availabilities = PrioTicket::Availabilities.find(distributor_id: 1234, ticket_id: 123, identifier: "my-unique-order-abc-123", from_date: Time.now, until_date: Time.now+(60*60*24*7))
87
+ # or:
88
+ @availabilities = @ticket_details.availabilities(from_date: Time.now, until_date: Time.now+(60*60*24*7))
89
+ ```
90
+
91
+ ### Reservation
92
+ To reserve a date, use the `PrioTicket::Reservation` class:
93
+ ```ruby
94
+ @reservation = PrioTicket::Reservation.new(
95
+ identifier: "my-unique-order-abc-123",
96
+ distributor_id: 1234,
97
+ ticket_id: 123,
98
+ from_date_time: @availabilities.first.from_date_time,
99
+ to_date_time: @availabilities.first.to_date_time,
100
+ booking_details: [{ticket_type: "ADULT", count: 1}],
101
+ distributor_reference: "TEST_RESERVATION"
102
+ )
103
+ # at this point, the reservation is only made in memory, but not yet
104
+ # send to the PrioTicket server. To make in final, call `save`.
105
+
106
+ @reservation.save
107
+ # => #<PrioTicket::Reservation @identifier="test-1522067114", @distributor_id=1234, @ticket_id=123, @from_date_time="2018-03-26T23:00:00+02:00", @to_date_time="2018-03-26T23:59:00+02:00", @booking_details=[#<OpenStruct ticket_type="ADULT", count=1>], @distributor_reference="TEST_RESERVATION", @booking_status="Reserved", @reservation_reference="YYY2067115376XXX">
108
+
109
+ # Cancel this reservation:
110
+ @reservation.cancel
111
+ @reservation.booking_status #=> "Cancelled"
112
+ ```
113
+
114
+ ### Booking
115
+ To make a booking, please take note of the official API Documentation: for tickets of type_2 and type_3, a `from_date_time` and `to_date_time` must be present.
116
+
117
+ Example code in section below.
118
+
119
+ ## Full example
120
+ All the steps are combined in the example below:
121
+ 1. Setup the API credentials
122
+ 2. Get a list of all the tickets/products
123
+ 3. Find out details of a specific ticket
124
+ 4. Get availability
125
+ 5. Make a booking
126
+ 6. Get status / cancel booking
127
+
128
+ ```ruby
129
+
130
+ # step 1
131
+ # config/development.rb (in case of Ruby on Rails App)
132
+ config.prioticcket.api_key = "MY-API-KEY"
133
+ config.prioticcket.environment = "test"
134
+
135
+ # Code below goes in a controller or model, handling the application logic
136
+
137
+ # step 2
138
+ @ticket_list = PrioTicket::TicketList.find(distributor_id: 1234, identifier: "test-123")
139
+
140
+ # step 3
141
+ @ticket = @ticket_list.tickets.first.details
142
+ #=> <PrioTicket::TicketDetails> includes name, prices, etc.
143
+
144
+ # step 4
145
+ # method defaults to 3 weeks ahead, you can provice from_date_time and to_date_time
146
+ @available_times = @ticket.availabilities
147
+
148
+ # step 5 - book first available time
149
+ @booking = PrioTicket::Booking.new(
150
+ identifier: "test-123",
151
+ distributor_id: 1234,
152
+ booking_type: {
153
+ ticket_id: @ticket.ticket_id,
154
+ booking_details: [{
155
+ ticket_type: "ADULT",
156
+ count: 2,
157
+ extra_options: []
158
+ }]
159
+ },
160
+ booking_name: "John Doe",
161
+ booking_email: "john@example.com",
162
+ contact: {
163
+ address: {
164
+ street: "Amstel 1",
165
+ postal_code: "1011 PN",
166
+ city: "Amsterdam"
167
+ },
168
+ phonenumber: "0643210123"
169
+ },
170
+ notes: ["This is a test booking"],
171
+ product_language: "en",
172
+ distributor_reference: "ABC123456"
173
+ )
174
+
175
+ # the booking is now made in memory, but not yet final
176
+ @booking.confirmed?
177
+ # => false
178
+
179
+ @booking.save
180
+ # => <PrioTicket::Booking> object, with status and barcodes
181
+
182
+ @booking.confirmed?
183
+ # => true
184
+
185
+ @booking.cancel
186
+ @booking.confirmed?
187
+ # => false
188
+ @booking.canceled?
189
+ # => true
190
+
191
+ @booking.booking_reference # => 123ABC456XYZ
192
+
193
+ # another way to ask for the status of a booking:
194
+ @booking = PrioTicket::Booking.get_status(
195
+ identifier: @booking.identifier,
196
+ distributor_id: DIST_ID,
197
+ booking_reference: "123ABC456XYZ",
198
+ distributor_reference: "ABC123456
199
+ )
200
+ @booking.status # => "Cancelled"
201
+ ```
202
+
203
+ ## Contributing
204
+
205
+ Bug reports and pull requests are welcome on GitHub at https://github.com/henkm/prioticket.
206
+
207
+
208
+ ## License
209
+
210
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). No rights can be derrived from using this library.
211
+
212
+ This gem is made with love by the smart people at [Eskes Media B.V.](https://www.eskesmedia.nl) and [DagjeWeg.NL Tickets](https://www.dagjewegtickets.nl)
213
+ PrioTicket is not involved with this project and has no affiliation with Eskes Media B.V.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "prioticket"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,94 @@
1
+ module PrioTicket
2
+
3
+ # The communication layer implements all the methods available in the PrioTicket API
4
+ # NOTE: You need to request access to view the documentation.
5
+ # https://support.prioticket.com/docs/
6
+ class API
7
+
8
+ #
9
+ # Returns the API endpoint to use
10
+ #
11
+ # @return [type] [description]
12
+ def self.endpoint
13
+ if PrioTicket::Config.environment.to_s == "test"
14
+ "https://test-api.prioticket.com/v2.4/booking_service"
15
+ else
16
+ "https://api.prioticket.com/v2.4/booking_service"
17
+ end
18
+ end
19
+
20
+ # The request authentication key will contain the following items:
21
+ # (a) API Key Token
22
+ # (b) Request Identifier
23
+ #
24
+ # The API Key Token information for the TEST and LIVE environment will be sent in a separate mail.
25
+ # The Request Identifier should be an unique string generated by the initiator. Common examples are
26
+ # a timestamp, booking reference or UUID.The request authentication key will be computed per request
27
+ # as follows:
28
+ #
29
+ def self.request_authentication_key(request_identifier="")
30
+ # 1. Create a string with format <x-request-identifier>:<apikeytoken> where x-request-identifier
31
+ # and apikeytoken are respective strings.
32
+ step_1_string = "#{request_identifier}:#{Config.api_key}"
33
+
34
+ # 2. Convert the string from step 1 to byte array using UTF-8 encoding.
35
+ step_2_string = step_1_string.encode('utf-8')
36
+
37
+ # 3. Compute the SHA-256 hash for the byte array from step 2. The result will be a byte array.
38
+ step_3_string = Digest::SHA256.digest(step_2_string).strip
39
+
40
+ # 4. Base64 encode the byte array as computed in step 3.
41
+ # This string will be the x-request-authentication key for this request.
42
+ step_4_string = Base64.encode64(step_3_string).strip
43
+
44
+ return step_4_string
45
+ end
46
+
47
+ #
48
+ # Computes the request header
49
+ # @param request_identifier="" [type] A unique request identifier,
50
+ # e.g. timestamp order_id, booking_reference or UUID.
51
+ #
52
+ # @return [Hash] the header details for API calls
53
+ def self.request_header(request_identifier="")
54
+ {
55
+ content_type: "application/json",
56
+ x_request_authentication: request_authentication_key(request_identifier),
57
+ x_request_identifier: request_identifier
58
+ }
59
+ end
60
+
61
+
62
+ #
63
+ # Makes a HTTP POST call to the endpoint en returns the response
64
+ #
65
+ # @param request_body [type] [description]
66
+ # @param request_identifier [type] [description]
67
+ #
68
+ # @return OpenStruct object with nested methods.
69
+ def self.call(request_body, request_identifier, verbose=false)
70
+ values = request_body.to_json
71
+ headers = request_header(request_identifier)
72
+ if verbose || PrioTicket::Config.verbose == true
73
+ puts "Calling with:"
74
+ puts "Identifier: #{request_identifier}"
75
+ puts "Header: #{headers.to_json}"
76
+ puts "Body: #{values}"
77
+ puts "Endpoint: #{endpoint}"
78
+ end
79
+ raise PrioTicketError.new "Request Identifier is not present, please provide an @identifier" if request_identifier.nil? || request_identifier == ''
80
+ begin
81
+ response = RestClient.post endpoint, values, headers
82
+ rescue RestClient::ExceptionWithResponse => e
83
+ if verbose || PrioTicket::Config.verbose == true
84
+ puts "Error: #{e.response}"
85
+ end
86
+ error_json = JSON.parse(e.response)
87
+ message = "#{error_json["error_message"]} (#{error_json["error_code"]}) - #{e}"
88
+ raise PrioTicketError.new message
89
+ end
90
+ object = JSON.parse(response.body)
91
+ return object
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,89 @@
1
+ module PrioTicket
2
+
3
+ # This endpoint should be called in order to get up-to-date availability
4
+ # information for a product with managed capacity. The response will contain
5
+ # the availability for each time slot of the requested product that lies within
6
+ # the specified date range. Time slots will not be omitted in case of no availability.
7
+ # Neither will a NO_AVAILABILITY error be returned in that case.
8
+ # Instead, an explicit vacancy of zero should be expected.
9
+ #
10
+ class Availabilities
11
+ attr_accessor :from_date_time
12
+ attr_accessor :to_date_time
13
+ attr_accessor :vacancies
14
+
15
+
16
+ def initialize(args=nil)
17
+ return if args.nil?
18
+ args.each do |k,v|
19
+ PrioTicket.parse_json_value(self, k,v)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Calls the request type 'availabilities' with given
25
+ # details and retruns an array of Availabilities objects
26
+ #
27
+ # @param distributor_id Integer
28
+ # @return Array
29
+ def self.find(distributor_id: nil, ticket_id: nil, from_date: nil, until_date: nil, identifier: nil)
30
+ result = PrioTicket::API.call(request_body(ticket_id: ticket_id, distributor_id: distributor_id, from_date: from_date, until_date: until_date), identifier, false)
31
+ list = []
32
+ for a in result["data"]["availabilities"]
33
+ list << Availabilities.new(a)
34
+ end
35
+ return list
36
+ end
37
+
38
+ #
39
+ # Computes the request body to send to the API endpoint
40
+ # @param distributor_id Integer
41
+ # @param ticket_id Integer
42
+ # @param from_date String
43
+ # @param until_date String
44
+ #
45
+ # @return Hash
46
+ def self.request_body(distributor_id: nil, ticket_id: nil, from_date: nil, until_date: nil)
47
+ {
48
+ request_type: "availabilities",
49
+ data: {
50
+ distributor_id: distributor_id,
51
+ ticket_id: ticket_id,
52
+ from_date: PrioTicket.parsed_date(from_date),
53
+ until_date: PrioTicket.parsed_date(until_date)
54
+ }
55
+ }
56
+ end
57
+
58
+
59
+ def reserve
60
+ # {
61
+ # "request_type": "reserve",
62
+ # "data": {
63
+ # "distributor_id": "501",
64
+ # "ticket_id": "509",
65
+ # "pickup_point_id": "Wyndham_Apollo_hotel",
66
+ # "from_date_time": "2017-11-22T09:00:00+01:00",
67
+ # "to_date_time": "2017-11-23T09:00:00+01:00",
68
+ # "booking_details": [
69
+ # {
70
+ # "ticket_type": "ADULT",
71
+ # "count": 1
72
+ # }
73
+ # ],
74
+ # "distributor_reference": "ABC123456"
75
+ # }
76
+ # }
77
+
78
+ # {
79
+ # "response_type": "reserve",
80
+ # "data": {
81
+ # "reservation_reference": "123456789",
82
+ # "distributor_reference": "ABC123456",
83
+ # "booking_status": "Reserved"
84
+ # }
85
+ # }
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,197 @@
1
+ module PrioTicket
2
+
3
+ # Describes a Booking
4
+ # This API is called to get a ticket booked and get a barcode/QR-code in response.
5
+ # The booking API provides a booking reference in response.
6
+ # There are 5 different booking options:
7
+ # - Booking of ticket without timeslot (ticket_class 1).
8
+ # - Booking of ticket with timeslot (ticket_class 2/ticket_class 3),
9
+ # without reservation_reference.
10
+ # - Booking of ticket with timeslot (ticket_class 2/ticket_class 3),
11
+ # with reservation_reference.
12
+ #
13
+ class Booking
14
+
15
+ attr_accessor :identifier
16
+ attr_accessor :distributor_id
17
+ # attr_accessor :booking_type
18
+ attr_accessor :booking_type
19
+ attr_accessor :booking_name
20
+ attr_accessor :booking_email
21
+ attr_accessor :notes
22
+ attr_accessor :contact
23
+ attr_accessor :product_language
24
+ attr_accessor :distributor_reference
25
+ attr_accessor :reservation_reference
26
+
27
+
28
+ # contact details
29
+ attr_accessor :phone_number
30
+ attr_accessor :street
31
+ attr_accessor :postal_code
32
+ attr_accessor :city
33
+
34
+ # completed booking attrs
35
+ attr_accessor :booking_reference
36
+ attr_accessor :booking_status
37
+ attr_accessor :booking_details
38
+
39
+ def initialize(args)
40
+ return if args.nil?
41
+ args.each do |k,v|
42
+ PrioTicket.parse_json_value(self, k,v)
43
+ end
44
+ end
45
+
46
+ #
47
+ # Sends the reservation request tot the API
48
+ #
49
+ def save
50
+ request_booking
51
+ end
52
+
53
+
54
+ def canceled
55
+ booking_status == "Cancelled"
56
+ end
57
+ alias_method :canceled?, :canceled
58
+
59
+
60
+ def success
61
+ booking_status == "Confirmed"
62
+ end
63
+ for meth in [:success?, :confirmed, :confirmed?]
64
+ alias_method meth, :success
65
+ end
66
+
67
+
68
+ # Fetches information from ticket_details,
69
+ # to validate the input for this booking.
70
+ # e.g. if ticket_type == 2, from/to date are required.
71
+ #
72
+ # @return [type] [description]
73
+ def ticket
74
+ begin
75
+ @ticket ||= PrioTicket::TicketDetails.find(distributor_id: distributor_id, ticket_id: booking_type['ticket_id'], identifier: identifier)
76
+ rescue
77
+ false
78
+ end
79
+ end
80
+
81
+
82
+ #
83
+ # Cancels a Booking
84
+ #
85
+ # @return Booking
86
+ def self.cancel(distributor_id: nil, booking_reference: nil, distributor_reference: nil, identifier: nil)
87
+ body = {
88
+ request_type: "cancel_booking",
89
+ data: {
90
+ distributor_id: distributor_id,
91
+ booking_reference: booking_reference,
92
+ distributor_reference: booking_reference
93
+ }
94
+ }
95
+ result = PrioTicket::API.call(body, identifier)
96
+ booking = PrioTicket::Booking.new(result["data"])
97
+ return booking
98
+ end
99
+
100
+ #
101
+ # Gets the status from a Booking
102
+ #
103
+ # @return Booking
104
+ def self.get_status(distributor_id: nil, booking_reference: nil, distributor_reference: nil, identifier: nil)
105
+ body = {
106
+ request_type: "booking_status",
107
+ data: {
108
+ distributor_id: distributor_id,
109
+ booking_reference: booking_reference,
110
+ distributor_reference: booking_reference
111
+ }
112
+ }
113
+ result = PrioTicket::API.call(body, identifier)
114
+ booking = PrioTicket::Booking.new(result["data"])
115
+ return booking
116
+ end
117
+
118
+ private
119
+
120
+ #
121
+ # Sends the reservation request to the API endpoint
122
+ # and enriches current object with status and reference.
123
+ #
124
+ def request_booking
125
+ result = PrioTicket::API.call(request_body, identifier)
126
+ parse_result(result)
127
+ end
128
+
129
+
130
+ #
131
+ # Computes the details to send to the API
132
+ #
133
+ # @return Hash
134
+ def request_body
135
+ for att in [:distributor_id, :booking_type, :booking_name, :booking_email, :contact, :notes, :product_language, :distributor_reference]
136
+ raise PrioTicketError.new("Booking is missing attribute `#{att}` (Hash)") unless send(att)
137
+ end
138
+ body = {
139
+ request_type: "booking",
140
+ data: {
141
+ distributor_id: distributor_id,
142
+ booking_type: validated_booking_type_hash,
143
+ booking_name: booking_name,
144
+ booking_email: booking_email,
145
+ contact: PrioTicket.openstruct_to_hash(contact).to_h,
146
+ notes: notes.to_a,
147
+ product_language: product_language,
148
+ distributor_reference: distributor_reference
149
+ }
150
+ }
151
+
152
+ # add pickuppoint to body, if present
153
+ # body[:data][:pickup_point_id] = pickup_point_id if pickup_point_id
154
+ return body
155
+ end
156
+
157
+ #
158
+ # Calculates and validates the information for 'booking_type'
159
+ #
160
+ # @return Hash
161
+ def validated_booking_type_hash
162
+
163
+ # loops through all the booking details and raises error
164
+ # if from/to date_time are not present.
165
+ if ticket
166
+ if [2,3].include?(ticket.ticket_class)
167
+ unless booking_type.from_date_time && booking_type.to_date_time
168
+ err_msg = "The `booking_type` attribute requires a from_date_time and to_date_time for a ticket of ticket_class #{ticket.ticket_class}."
169
+ raise PrioTicketError.new(err_msg)
170
+ end
171
+ end
172
+ end
173
+ data = {}
174
+
175
+ data[:ticket_id] = booking_type.ticket_id unless booking_type.reservation_reference
176
+ data[:booking_details] = booking_type.booking_details.map{|bd| PrioTicket.openstruct_to_hash(bd)} unless booking_type.reservation_reference
177
+ data[:reservation_reference] = booking_type.reservation_reference if booking_type.reservation_reference
178
+
179
+ if booking_type.from_date_time && booking_type.to_date_time
180
+ data[:from_date_time] = booking_type.from_date_time
181
+ data[:to_date_time] = booking_type.to_date_time
182
+ end
183
+ return data
184
+ end
185
+
186
+ #
187
+ # Parses the return value from the API
188
+ #
189
+ def parse_result(result)
190
+ self.booking_status = result["data"]["booking_status"]
191
+ self.booking_reference = result["data"]["booking_reference"]
192
+ PrioTicket.parse_json_value(self, :booking_details, result["data"]["booking_details"])
193
+ end
194
+
195
+
196
+ end
197
+ end