tickethub 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/lib/tickethub/address.rb +5 -0
  5. data/lib/tickethub/app/package.rb +9 -0
  6. data/lib/tickethub/app/subscription.rb +11 -0
  7. data/lib/tickethub/app.rb +36 -0
  8. data/lib/tickethub/category.rb +7 -0
  9. data/lib/tickethub/collection.rb +150 -0
  10. data/lib/tickethub/connection.rb +140 -0
  11. data/lib/tickethub/contact.rb +5 -0
  12. data/lib/tickethub/endpoint.rb +36 -0
  13. data/lib/tickethub/errors.rb +34 -0
  14. data/lib/tickethub/exceptions.rb +73 -0
  15. data/lib/tickethub/formats/form_format.rb +17 -0
  16. data/lib/tickethub/formats/json_format.rb +25 -0
  17. data/lib/tickethub/formats.rb +35 -0
  18. data/lib/tickethub/helpers.rb +108 -0
  19. data/lib/tickethub/request.rb +130 -0
  20. data/lib/tickethub/resource.rb +279 -0
  21. data/lib/tickethub/response/headers.rb +31 -0
  22. data/lib/tickethub/response.rb +49 -0
  23. data/lib/tickethub/supplier/answer.rb +11 -0
  24. data/lib/tickethub/supplier/app.rb +9 -0
  25. data/lib/tickethub/supplier/bill.rb +11 -0
  26. data/lib/tickethub/supplier/booking.rb +39 -0
  27. data/lib/tickethub/supplier/card.rb +11 -0
  28. data/lib/tickethub/supplier/coupon.rb +14 -0
  29. data/lib/tickethub/supplier/customer.rb +15 -0
  30. data/lib/tickethub/supplier/element.rb +11 -0
  31. data/lib/tickethub/supplier/fee.rb +15 -0
  32. data/lib/tickethub/supplier/gateway/handpoint.rb +8 -0
  33. data/lib/tickethub/supplier/gateway/ideal.rb +8 -0
  34. data/lib/tickethub/supplier/gateway/paypal.rb +8 -0
  35. data/lib/tickethub/supplier/gateway/stripe.rb +8 -0
  36. data/lib/tickethub/supplier/gateway.rb +16 -0
  37. data/lib/tickethub/supplier/invoice.rb +7 -0
  38. data/lib/tickethub/supplier/message/email.rb +8 -0
  39. data/lib/tickethub/supplier/message/sms.rb +8 -0
  40. data/lib/tickethub/supplier/message.rb +20 -0
  41. data/lib/tickethub/supplier/option.rb +18 -0
  42. data/lib/tickethub/supplier/order.rb +51 -0
  43. data/lib/tickethub/supplier/package.rb +9 -0
  44. data/lib/tickethub/supplier/payment/card.rb +18 -0
  45. data/lib/tickethub/supplier/payment/cash.rb +8 -0
  46. data/lib/tickethub/supplier/payment/credit.rb +8 -0
  47. data/lib/tickethub/supplier/payment/direct.rb +8 -0
  48. data/lib/tickethub/supplier/payment/gratuity.rb +8 -0
  49. data/lib/tickethub/supplier/payment.rb +34 -0
  50. data/lib/tickethub/supplier/product.rb +54 -0
  51. data/lib/tickethub/supplier/question.rb +11 -0
  52. data/lib/tickethub/supplier/rate.rb +16 -0
  53. data/lib/tickethub/supplier/receipt.rb +11 -0
  54. data/lib/tickethub/supplier/reseller.rb +36 -0
  55. data/lib/tickethub/supplier/scan.rb +17 -0
  56. data/lib/tickethub/supplier/season.rb +16 -0
  57. data/lib/tickethub/supplier/subscription.rb +11 -0
  58. data/lib/tickethub/supplier/tax.rb +16 -0
  59. data/lib/tickethub/supplier/template.rb +11 -0
  60. data/lib/tickethub/supplier/ticket.rb +25 -0
  61. data/lib/tickethub/supplier/tier.rb +20 -0
  62. data/lib/tickethub/supplier/user.rb +9 -0
  63. data/lib/tickethub/supplier/variant.rb +10 -0
  64. data/lib/tickethub/supplier/voucher.rb +23 -0
  65. data/lib/tickethub/supplier.rb +86 -0
  66. data/lib/tickethub/token.rb +9 -0
  67. data/lib/tickethub/user/app.rb +5 -0
  68. data/lib/tickethub/user/supplier.rb +5 -0
  69. data/lib/tickethub/user.rb +38 -0
  70. data/lib/tickethub/version.rb +3 -0
  71. data/lib/tickethub.rb +26 -0
  72. data/tickethub.gemspec +25 -0
  73. metadata +209 -0
@@ -0,0 +1,108 @@
1
+ require 'uri'
2
+
3
+ module Tickethub
4
+ module Helpers extend self
5
+ def to_path(*params)
6
+ params.map(&:to_s).reject(&:empty?) * '/'
7
+ end
8
+
9
+ def camelize(value)
10
+ value.to_s.split('_').map {|w| w.capitalize }.join
11
+ end
12
+
13
+ def deep_merge(hash, other_hash)
14
+ hash.merge(other_hash) do |key, oldval, newval|
15
+ oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
16
+ newval = newval.to_hash if newval.respond_to?(:to_hash)
17
+ oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? deep_merge(oldval, newval) : newval
18
+ end
19
+ end
20
+
21
+ # Stolen from Rack:
22
+
23
+ DEFAULT_SEP = /[&;] */n
24
+
25
+ def to_param(value, prefix = nil)
26
+ case value
27
+ when Array
28
+ value.map { |v|
29
+ to_param(v, "#{prefix}[]")
30
+ }.join("&")
31
+ when Hash
32
+ value.map { |k, v|
33
+ to_param(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
34
+ }.join("&")
35
+ else
36
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
37
+ "#{prefix}=#{escape(value)}"
38
+ end
39
+ end
40
+
41
+ def from_param(param)
42
+ Rack::Utils.parse_nested_query(param)
43
+ (value || '').split('&').each do |res|
44
+ key, value = res.split('=')
45
+ @params[key] = value
46
+ end
47
+ end
48
+
49
+ def from_param(qs, d = nil)
50
+ params = {}
51
+
52
+ (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p|
53
+ k, v = p.split('=', 2).map { |s| unescape(s) }
54
+
55
+ normalize_params(params, k, v)
56
+ end
57
+
58
+ params
59
+ end
60
+
61
+ def escape(s)
62
+ URI.encode_www_form_component(s)
63
+ end
64
+
65
+ if defined?(::Encoding)
66
+ def unescape(s, encoding = Encoding::UTF_8)
67
+ URI.decode_www_form_component(s, encoding)
68
+ end
69
+ else
70
+ def unescape(s, encoding = nil)
71
+ URI.decode_www_form_component(s, encoding)
72
+ end
73
+ end
74
+
75
+ protected
76
+
77
+ def normalize_params(params, name, v = nil)
78
+ name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
79
+ k = $1 || ''
80
+ after = $' || ''
81
+
82
+ return if k.empty?
83
+
84
+ if after == ""
85
+ params[k] = v
86
+ elsif after == "[]"
87
+ params[k] ||= []
88
+ raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
89
+ params[k] << v
90
+ elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
91
+ child_key = $1
92
+ params[k] ||= []
93
+ raise TypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array)
94
+ if params[k].last.kind_of?(Hash) && !params[k].last.key?(child_key)
95
+ normalize_params(params[k].last, child_key, v)
96
+ else
97
+ params[k] << normalize_params(params.class.new, child_key, v)
98
+ end
99
+ else
100
+ params[k] ||= params.class.new
101
+ raise TypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params[k].kind_of?(Hash)
102
+ params[k] = normalize_params(params[k], after, v)
103
+ end
104
+
105
+ return params
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,130 @@
1
+ module Tickethub
2
+ class Request
3
+ attr_reader :options, :format, :url
4
+ attr_accessor :params, :body, :method, :headers
5
+
6
+ # Connection options
7
+ attr_accessor :proxy, :user, :password, :auth_type, :timeout, :ssl_options
8
+
9
+ def initialize(url, options = {})
10
+ @url = url.to_s
11
+
12
+ @options = options
13
+ @options.each do |key, val|
14
+ method = "#{key}="
15
+ send(method, val) if respond_to?(method)
16
+ end
17
+
18
+ self.method ||= :get
19
+ self.params ||= {}
20
+ self.headers ||= {}
21
+ self.format ||= :form
22
+ end
23
+
24
+ def format=(mime_or_format)
25
+ @format = mime_or_format.is_a?(Symbol) ?
26
+ Formats[mime_or_format].new : mime_or_format
27
+ end
28
+
29
+ def url=(value)
30
+ @url = value
31
+ @uri = nil
32
+ @url
33
+ end
34
+
35
+ def uri
36
+ return @uri if @uri
37
+
38
+ url = @url.match(/\Ahttps?:\/\//) ? @url : "http://#{@url}"
39
+
40
+ @uri = URI.parse(url)
41
+ @uri.path = '/' if @uri.path.empty?
42
+
43
+ if @uri.query
44
+ @params.merge!(Helpers.from_param(@uri.query))
45
+ @uri.query = nil
46
+ end
47
+
48
+ @uri
49
+ end
50
+
51
+ def path
52
+ uri.path
53
+ end
54
+
55
+ def execute
56
+ if encoded?
57
+ result = connection.send(method, path, encoded, build_headers)
58
+ else
59
+ result = connection.send(method, query_path, build_headers)
60
+ end
61
+
62
+ Response.new(result)
63
+
64
+ rescue Redirection => error
65
+ raise error unless error.response['Location']
66
+
67
+ location = URI.parse(error.response['Location'])
68
+
69
+ # Path is relative
70
+ unless location.host
71
+ location = URI.join(uri, location)
72
+ end
73
+
74
+ self.url = location.to_s
75
+ execute
76
+ end
77
+
78
+ protected
79
+
80
+ def connection
81
+ Connection.new(uri,
82
+ :proxy => proxy,
83
+ :timeout => timeout,
84
+ :ssl_options => ssl_options
85
+ )
86
+ end
87
+
88
+ def content_type_headers
89
+ if encoded?
90
+ {'Content-Type' => format.mime_type}
91
+ else
92
+ {}
93
+ end
94
+ end
95
+
96
+ def auth_headers
97
+ if auth_type == :bearer
98
+ { 'Authorization' => "Bearer #{@password}" }
99
+ elsif auth_type == :basic
100
+ { 'Authorization' => 'Basic ' + ["#{@user}:#{@password}"].pack('m').delete("\r\n") }
101
+ else
102
+ { }
103
+ end
104
+ end
105
+
106
+ def build_headers
107
+ auth_headers
108
+ .merge(content_type_headers)
109
+ .merge(headers)
110
+ end
111
+
112
+ def query_path
113
+ query_path = path
114
+
115
+ if params.any?
116
+ query_path += '?' + Helpers.to_param(params)
117
+ end
118
+
119
+ query_path
120
+ end
121
+
122
+ def encoded?
123
+ [:post, :patch].include?(method)
124
+ end
125
+
126
+ def encoded
127
+ params.any? ? format.encode(params) : body
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,279 @@
1
+ require 'money'
2
+ require 'iso8601'
3
+ require 'timezone'
4
+ require 'countries'
5
+
6
+ require_relative 'collection'
7
+
8
+ module Tickethub
9
+ class Resource
10
+
11
+ class << self
12
+ attr_reader :endpoint
13
+
14
+ def all(params = {})
15
+ Tickethub::Collection.new @endpoint, self, params
16
+ end
17
+
18
+ def polymorphic(type, options = {})
19
+ self.superclass.register_type type, **options
20
+ end
21
+
22
+ def register_type(type, klass: self, attribute: :type) # klass, attribute
23
+ registered_types[type] = { klass: klass, attribute: attribute }
24
+ end
25
+
26
+ def registered_types
27
+ @registered_types ||= {}
28
+ end
29
+
30
+ def scopes
31
+ @scopes ||= {}
32
+ end
33
+
34
+ def path(value, options = {})
35
+ @singleton = options.delete(:singleton) || false
36
+ @endpoint = Tickethub.endpoint[value, options]
37
+ end
38
+
39
+ def scope(key, proc = -> (params = {}) { self.scope key, params })
40
+ self.scopes[key] = proc
41
+ end
42
+
43
+ def singleton?
44
+ !! @singleton
45
+ end
46
+
47
+ def attribute(key, options = nil)
48
+ options.nil?? (self.attributes[key] ||= {}).dup
49
+ : self.attributes[key] = options
50
+ end
51
+
52
+ def attributes
53
+ @attributes ||= {}
54
+ end
55
+
56
+ def load_value(key, value, object)
57
+ return nil if value.nil? || (value.is_a?(String) && value.empty?)
58
+ case self.attribute(key)[:type]
59
+ when :date
60
+ case value
61
+ when String then ISO8601::Date.new(value)
62
+ else raise ArgumentError, 'invalid date value: ' + value
63
+ end
64
+ when :datetime
65
+ case value
66
+ when String then ISO8601::DateTime.new(value)
67
+ else raise ArgumentError, 'invalid datetime value: ' + value
68
+ end
69
+ when :time
70
+ case value
71
+ when String then ISO8601::Time.new(value)
72
+ else raise ArgumentError, 'invalid time value: ' + value
73
+ end
74
+ when :duration
75
+ case value
76
+ when String then ISO8601::Duration.new(value)
77
+ else raise ArgumentError, 'invalid time value: ' + value
78
+ end
79
+ when :money
80
+ currency = Money::Currency.new(object.currency)
81
+ raise ArgumentError, 'invalid money currency' if currency.blank?
82
+
83
+ case value
84
+ when Fixnum then Money.new(value, currency)
85
+ when Numeric, String
86
+ currency = Money::Currency.wrap(currency)
87
+ Money.new(value.to_d * currency.subunit_to_unit, currency)
88
+ else raise ArgumentError, 'invalid money value: ' + value
89
+ end
90
+ when :currency
91
+ case value
92
+ when String then Money::Currency.new(value)
93
+ else raise ArgumentError, 'invalid currency value: ' + value
94
+ end
95
+ when :timezone
96
+ case value
97
+ when String then Timezone::Zone.new(zone: value)
98
+ else raise ArgumentError, 'invalid timezone value: ' + value
99
+ end
100
+ when :country
101
+ case value
102
+ when String then Country.new(value)
103
+ else raise ArgumentError, 'invalid country value: ' + value
104
+ end
105
+ else value
106
+ end
107
+ end
108
+
109
+ def dump_value(key, value)
110
+ case self.attribute(key)[:type]
111
+ when :date then value.iso8601
112
+ when :datetime then value.iso8601
113
+ when :time then value.iso8601[10..-1]
114
+ when :duration then value.iso8601
115
+ when :money then value.fractional
116
+ when :timezone then value.zone
117
+ when :country then value.alpha2
118
+ when :currency then value.iso_code
119
+ else value
120
+ end
121
+ end
122
+
123
+ def serialize(attributes)
124
+ attributes.collect do |key, value|
125
+ [key, dump_value(key, value)]
126
+ end.to_h
127
+ end
128
+
129
+ def load(endpoint, attributes = nil)
130
+ attributes ||= endpoint.get
131
+
132
+ klass = registered_types.find do |type, options|
133
+ attributes[options[:attribute].to_s] == type
134
+ end
135
+
136
+ klass = klass ? klass[1][:klass] : self
137
+
138
+ if id = attributes['id']
139
+ endpoint = klass.endpoint[id, endpoint.options]
140
+ end
141
+
142
+ klass.new endpoint, attributes
143
+ end
144
+
145
+ def association(key, klass, path: key)
146
+ define_method key do
147
+ instance_variable_defined?("@#{key}") ? instance_variable_get("@#{key}") :
148
+ instance_variable_set("@#{key}", klass.load(@endpoint[path]))
149
+ end
150
+
151
+ define_method "#{key}=" do |value|
152
+ instance_variable_set "@#{key}", ((value.nil? || value.is_a?(klass)) ? value :
153
+ klass.load(@endpoint[path], value))
154
+ end
155
+ end
156
+
157
+ def collection(key, klass, path: key, &block)
158
+
159
+ define_method key do |params = {}|
160
+ (instance_variable_defined?("@#{key}") ? instance_variable_get("@#{key}") :
161
+ (sinleton? || id?) ? instance_variable_set("@#{key}",
162
+ Tickethub::Collection.new(@endpoint[path], klass, params)) : []).tap do |collection|
163
+ collection.instance_eval &block if block
164
+ end
165
+ end
166
+
167
+ define_method "#{key}=" do |values|
168
+ instance_variable_set "@#{key}", (singleton? || id?) ?
169
+ (Tickethub::Collection.new(@endpoint[path], klass).tap do |collection|
170
+ collection.cache = values
171
+ end) : values.collect { |value| klass.load @endpoint, value }
172
+ end
173
+ end
174
+ end
175
+
176
+ attr_accessor :endpoint
177
+
178
+ def initialize(endpoint, attributes = nil)
179
+ @endpoint = endpoint
180
+ attributes ||= endpoint.get
181
+
182
+ self.load attributes
183
+ end
184
+
185
+ def valid?
186
+ errors.nil? || errors.valid?
187
+ end
188
+
189
+ def update(attributes)
190
+ self.load @endpoint.patch(attributes).decoded
191
+ return true
192
+ rescue Tickethub::ResourceInvalid => err
193
+ self.load Tickethub::Response.new(err.response).decoded
194
+ return false
195
+ end
196
+
197
+ def destroy
198
+ self.load @endpoint.delete.decoded
199
+ end
200
+
201
+ def singleton?
202
+ !! @singleton
203
+ end
204
+
205
+ def respond_to?(method, include_priv = false)
206
+ @attributes.key?(method.to_s.remove(/[=\?]\Z/).to_sym) || super
207
+ end
208
+
209
+ def reload!
210
+ self.load @endpoint.get
211
+ end
212
+
213
+ def load(attributes)
214
+ @attributes = {}
215
+ attributes.each do |key, value|
216
+ send "#{key}=", value
217
+ end
218
+ return self
219
+ end
220
+
221
+ def [](key)
222
+ send key
223
+ end
224
+
225
+ def []=(key, value)
226
+ send "#{key}=", value
227
+ end
228
+
229
+ def ==(other)
230
+ self.hash == other.hash
231
+ end
232
+
233
+ def eql?(other)
234
+ self == other
235
+ end
236
+
237
+ def hash
238
+ id?? id.hash : super
239
+ end
240
+
241
+ def to_param
242
+ self.id
243
+ end
244
+
245
+ def errors
246
+ @errors ||= Tickethub::Errors.new @attributes[:errors]
247
+ end
248
+
249
+ def to_h
250
+ @attributes
251
+ end
252
+
253
+ def to_s
254
+ self.id?? id : super
255
+ end
256
+
257
+ def inspect
258
+ "#<#{self.class.name} #{to_h}>"
259
+ end
260
+
261
+ protected
262
+
263
+ def method_missing(method, *arguments)
264
+ if match = method.to_s.match(/^(.+)(=|\?)$/)
265
+ key = match[1].to_sym
266
+
267
+ case match[2]
268
+ when '='
269
+ @attributes[key] = self.class
270
+ .load_value(key, arguments.first, self)
271
+ when "?"
272
+ !! @attributes[key]
273
+ end
274
+ else
275
+ @attributes.key?(method) ? @attributes[method] : super
276
+ end
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,31 @@
1
+ module Tickethub
2
+ class Response #:nodoc:
3
+ class Headers
4
+ include ::Net::HTTPHeader
5
+
6
+ def initialize(header = {})
7
+ @header = header
8
+ end
9
+
10
+ def ==(other)
11
+ @header == other
12
+ end
13
+
14
+ def inspect
15
+ @header.inspect
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ if @header.respond_to?(name)
20
+ @header.send(name, *args, &block)
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def respond_to?(method)
27
+ super || @header.respond_to?(method)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ module Tickethub
2
+ class Response
3
+ attr_reader :response, :body, :headers, :parser
4
+
5
+ def initialize(response, parser = nil)
6
+ @response = response
7
+ @body = response.body
8
+ @headers = Headers.new(response.to_hash)
9
+ @format = Formats.for(headers.content_type)
10
+ @parser ||= @format && @format.new
11
+ end
12
+
13
+ def as_json
14
+ decoded
15
+ end
16
+
17
+ def to_json(*)
18
+ as_json.to_json
19
+ end
20
+
21
+ def code
22
+ response.code.to_i
23
+ end
24
+
25
+ alias_method :status, :code
26
+
27
+ def decoded
28
+ @decoded ||= parser ? parser.decode(body) : body
29
+ end
30
+
31
+ def respond_to?(name)
32
+ super || decoded.respond_to?(name) || response.respond_to?(name)
33
+ end
34
+
35
+ protected
36
+
37
+ def method_missing(name, *args, &block)
38
+ if decoded.respond_to?(name)
39
+ decoded.send(name, *args, &block)
40
+ elsif response.respond_to?(name)
41
+ response.send(name, *args, &block)
42
+ else
43
+ super
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ require_relative 'response/headers'
@@ -0,0 +1,11 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class Supplier::Answer < Resource
5
+ path '/supplier/answers'
6
+
7
+ require_relative 'question'
8
+
9
+ association :question, Supplier::Question
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Tickethub
2
+ class Supplier::App < Resource
3
+ path '/apps'
4
+
5
+ require_relative 'package'
6
+
7
+ collection :packages, Supplier::Package
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class Supplier::Bill < Resource
5
+ path '/supplier/bills'
6
+
7
+ require_relative 'receipt'
8
+
9
+ collection :receipts, Supplier::Receipt
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class Supplier::Booking < Resource
5
+ path '/supplier/bookings'
6
+
7
+ require_relative 'rate'
8
+ require_relative 'order'
9
+ require_relative 'ticket'
10
+ require_relative 'answer'
11
+ require_relative 'product'
12
+ require_relative 'variant'
13
+ require_relative 'message'
14
+ require_relative 'fee'
15
+
16
+ collection :tickets, Supplier::Ticket
17
+ collection :answers, Supplier::Answer
18
+ collection :messages, Supplier::Message
19
+ collection :fees, Supplier::Fee
20
+
21
+ association :order, Supplier::Order
22
+ association :rate, Supplier::Rate
23
+ association :coupon, Supplier::Coupon
24
+ association :product, Supplier::Product
25
+ association :variant, Supplier::Variant
26
+
27
+ attribute :amount, type: :money
28
+ attribute :tax, type: :money
29
+ attribute :total, type: :money
30
+
31
+ attribute :currency, type: :currency
32
+ attribute :valid_from, type: :datetime
33
+ attribute :expires_at, type: :datetime
34
+ attribute :timeout_at, type: :datetime
35
+ attribute :created_at, type: :datetime
36
+ attribute :updated_at, type: :datetime
37
+ attribute :cancelled_at, type: :datetime
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class Supplier::Card < Resource
5
+ path '/supplier/cards'
6
+
7
+ require_relative 'payment'
8
+
9
+ collection :payments, Supplier::Payment
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require_relative '../resource'
2
+
3
+ module Tickethub
4
+ class Supplier::Coupon < Resource
5
+ path '/supplier/coupons'
6
+
7
+ require_relative 'booking'
8
+ require_relative 'product'
9
+
10
+ collection :bookings, Supplier::Booking
11
+
12
+ association :product, Supplier::Product
13
+ end
14
+ end