t2_airtime 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +0 -2
  3. data/app/controllers/t2_airtime/accounts_controller.rb +15 -0
  4. data/app/controllers/t2_airtime/application_controller.rb +46 -0
  5. data/app/controllers/t2_airtime/countries_controller.rb +20 -0
  6. data/app/controllers/t2_airtime/operators_controller.rb +26 -0
  7. data/app/controllers/t2_airtime/products_controller.rb +21 -0
  8. data/app/controllers/t2_airtime/transactions_controller.rb +48 -0
  9. data/config/routes.rb +5 -6
  10. data/lib/t2_airtime/api.rb +279 -277
  11. data/lib/t2_airtime/base.rb +30 -29
  12. data/lib/t2_airtime/engine.rb +10 -11
  13. data/lib/t2_airtime/errors.rb +85 -89
  14. data/lib/t2_airtime/reply.rb +57 -39
  15. data/lib/t2_airtime/request.rb +70 -65
  16. data/lib/t2_airtime/serializer.rb +294 -313
  17. data/lib/t2_airtime/url.rb +6 -6
  18. data/lib/t2_airtime/util.rb +28 -30
  19. data/lib/t2_airtime/version.rb +1 -1
  20. data/lib/t2_airtime.rb +13 -14
  21. data/spec/dummy/bin/setup +0 -1
  22. data/spec/dummy/config/application.rb +20 -9
  23. data/spec/dummy/config/environments/development.rb +2 -2
  24. data/spec/dummy/config/environments/production.rb +2 -3
  25. data/spec/dummy/config/initializers/mime_types.rb +1 -0
  26. data/spec/dummy/config/puma.rb +3 -3
  27. data/spec/dummy/config/routes.rb +1 -1
  28. data/spec/dummy/config/spring.rb +2 -2
  29. data/spec/dummy/log/development.log +6942 -0
  30. data/spec/dummy/log/production.log +8 -0
  31. data/spec/dummy/tmp/cache/361/BB0/accounts +0 -0
  32. data/spec/dummy/tmp/cache/3DD/470/countries +0 -0
  33. data/spec/dummy/tmp/cache/446/4A0/products%2F4 +0 -0
  34. data/spec/dummy/tmp/cache/4AD/6A0/products%2F137 +0 -0
  35. data/spec/dummy/tmp/cache/4B2/750/products%2F439 +0 -0
  36. data/spec/dummy/tmp/cache/4DA/3C0/products%2F2105 +0 -0
  37. data/spec/dummy/tmp/cache/4DD/4D0/products%2F2720 +0 -0
  38. data/spec/dummy/tmp/cache/4DE/470/products%2F1524 +0 -0
  39. data/spec/dummy/tmp/cache/4DE/490/products%2F1623 +0 -0
  40. data/spec/dummy/tmp/cache/4DE/500/products%2F2901 +0 -0
  41. data/spec/dummy/tmp/cache/4DF/460/products%2F2074 +0 -0
  42. data/spec/dummy/tmp/cache/4E0/470/products%2F2075 +0 -0
  43. data/spec/dummy/tmp/cache/4E2/480/products%2F2149 +0 -0
  44. data/spec/dummy/tmp/cache/4E2/500/products%2F1573 +0 -0
  45. data/spec/dummy/tmp/cache/4E4/500/products%2F2448 +0 -0
  46. data/spec/dummy/tmp/cache/4E4/530/products%2F1827 +0 -0
  47. data/spec/dummy/tmp/cache/4E5/570/products%2F1693 +0 -0
  48. data/spec/dummy/tmp/cache/4E5/5B0/products%2F1972 +0 -0
  49. data/spec/dummy/tmp/cache/4E7/580/products%2F1767 +0 -0
  50. data/spec/dummy/tmp/cache/4EB/5E0/products%2F1789 +0 -0
  51. data/spec/dummy/tmp/cache/4EB/5F0/products%2F1879 +0 -0
  52. data/spec/dummy/tmp/cache/4EC/610/products%2F1889 +0 -0
  53. data/spec/dummy/tmp/cache/515/9E0/operators%2F701 +0 -0
  54. data/spec/dummy/tmp/cache/518/A50/operators%2F740 +0 -0
  55. data/spec/dummy/tmp/cache/519/A20/operators%2F705 +0 -0
  56. data/spec/dummy/tmp/cache/51A/A70/operators%2F661 +0 -0
  57. data/spec/dummy/tmp/cache/51C/A90/operators%2F663 +0 -0
  58. data/spec/dummy/tmp/cache/51C/AB0/operators%2F681 +0 -0
  59. data/spec/dummy/tmp/cache/51D/AA0/operators%2F664 +0 -0
  60. data/spec/dummy/tmp/cache/51D/AC0/operators%2F844 +0 -0
  61. data/spec/dummy/tmp/cache/51D/AD0/operators%2F691 +0 -0
  62. data/spec/dummy/tmp/cache/51F/AE0/operators%2F684 +0 -0
  63. data/spec/dummy/tmp/cache/521/AE0/operators%2F668 +0 -0
  64. data/spec/dummy/tmp/cache/521/AF0/operators%2F677 +0 -0
  65. data/spec/dummy/tmp/cache/522/AF0/operators%2F669 +0 -0
  66. data/spec/dummy/tmp/cache/522/B00/operators%2F678 +0 -0
  67. data/spec/dummy/tmp/cache/523/B10/operators%2F679 +0 -0
  68. data/spec/dummy/tmp/cache/523/B50/operators%2F796 +0 -0
  69. data/spec/dummy/tmp/cache/769/350/accounts%2Fcurrency +1 -0
  70. data/spec/dummy/tmp/cache/8B4/E50/countries%2Fserializer +167 -0
  71. data/spec/dummy/tmp/cache/91D/3D0/products%2F4%2Fserializer +17 -0
  72. data/spec/dummy/tmp/cache/984/980/products%2F137%2Fserializer +28 -0
  73. data/spec/dummy/tmp/cache/989/E40/products%2F439%2Fserializer +11 -0
  74. data/spec/dummy/tmp/cache/9B1/B30/products%2F2105%2Fserializer +18 -0
  75. data/spec/dummy/tmp/cache/9B4/EB0/products%2F2720%2Fserializer +19 -0
  76. data/spec/dummy/tmp/cache/9B5/F20/products%2F1524%2Fserializer +14 -0
  77. data/spec/dummy/tmp/cache/9B5/F40/products%2F1623%2Fserializer +33 -0
  78. data/spec/dummy/tmp/cache/9B5/FB0/products%2F2901%2Fserializer +9 -0
  79. data/spec/dummy/tmp/cache/9B6/FE0/products%2F2074%2Fserializer +17 -0
  80. data/spec/dummy/tmp/cache/9B7/0C0/products%2F2075%2Fserializer +17 -0
  81. data/spec/dummy/tmp/cache/9B9/270/products%2F2149%2Fserializer +8 -0
  82. data/spec/dummy/tmp/cache/9B9/2F0/products%2F1573%2Fserializer +56 -0
  83. data/spec/dummy/tmp/cache/9BB/4C0/products%2F1827%2Fserializer +35 -0
  84. data/spec/dummy/tmp/cache/9BC/5D0/products%2F1693%2Fserializer +17 -0
  85. data/spec/dummy/tmp/cache/9BC/610/products%2F1972%2Fserializer +10 -0
  86. data/spec/dummy/tmp/cache/9BE/780/products%2F1767%2Fserializer +27 -0
  87. data/spec/dummy/tmp/cache/9C2/B20/products%2F1789%2Fserializer +52 -0
  88. data/spec/dummy/tmp/cache/9C2/B30/products%2F1879%2Fserializer +28 -0
  89. data/spec/dummy/tmp/cache/9C3/C20/products%2F1889%2Fserializer +46 -0
  90. data/spec/dummy/tmp/cache/9EC/140/operators%2F701%2Fserializer +13 -0
  91. data/spec/dummy/tmp/cache/9EF/420/operators%2F740%2Fserializer +9 -0
  92. data/spec/dummy/tmp/cache/9F0/4C0/operators%2F705%2Fserializer +4 -0
  93. data/spec/dummy/tmp/cache/9F1/5E0/operators%2F661%2Fserializer +6 -0
  94. data/spec/dummy/tmp/cache/9F3/7A0/operators%2F663%2Fserializer +4 -0
  95. data/spec/dummy/tmp/cache/9F3/7C0/operators%2F681%2Fserializer +3 -0
  96. data/spec/dummy/tmp/cache/9F4/880/operators%2F664%2Fserializer +2 -0
  97. data/spec/dummy/tmp/cache/9F4/8A0/operators%2F844%2Fserializer +10 -0
  98. data/spec/dummy/tmp/cache/9F4/8B0/operators%2F691%2Fserializer +8 -0
  99. data/spec/dummy/tmp/cache/9F6/A60/operators%2F684%2Fserializer +2 -0
  100. data/spec/dummy/tmp/cache/9F8/C00/operators%2F668%2Fserializer +4 -0
  101. data/spec/dummy/tmp/cache/9F8/C10/operators%2F677%2Fserializer +5 -0
  102. data/spec/dummy/tmp/cache/9F9/CE0/operators%2F669%2Fserializer +6 -0
  103. data/spec/dummy/tmp/cache/9F9/CF0/operators%2F678%2Fserializer +14 -0
  104. data/spec/dummy/tmp/cache/9FA/DD0/operators%2F679%2Fserializer +4 -0
  105. data/spec/dummy/tmp/cache/9FA/E10/operators%2F796%2Fserializer +3 -0
  106. data/spec/dummy/tmp/caching-dev.txt +0 -0
  107. data/spec/rails_helper.rb +1 -1
  108. data/spec/spec_helper.rb +47 -49
  109. data/spec/t2_airtime_spec.rb +179 -181
  110. metadata +176 -3
  111. data/app/controllers/t2_airtime/airtime_controller.rb +0 -105
@@ -1,313 +1,294 @@
1
- module T2Airtime
2
-
3
- class Account
4
-
5
- def self.info
6
- reply = T2Airtime::API.api.account_info
7
- reply.success? ? serialize(reply.data, reply.headers[:date]) : []
8
- end
9
-
10
- def self.serialize(data, ts="#{Time.zone.now}")
11
- {
12
- type: "accounts",
13
- id: T2Airtime::API.api.user,
14
- attributes: {
15
- "type": data[:type],
16
- "name": data[:name],
17
- "currency": data[:currency],
18
- "balance": Float(data[:balance]),
19
- "wallet": Float(data[:wallet]),
20
- "fetched-at": T2Airtime::Util.format_time(ts)
21
- }
22
- }.as_json
23
- end
24
-
25
- end
26
-
27
- class Country
28
-
29
- def self.take(qty=5)
30
- reply = T2Airtime::API.api.country_list
31
- reply.success? ? serialize(reply.data, reply.headers[:date], qty) : []
32
- end
33
-
34
- def self.serialize(data, ts="#{Time.zone.now}", qty=nil)
35
- return [] if data[:countryid].nil?
36
- names = data[:country].split(",")
37
- ids = data[:countryid].split(",")
38
- ids.take(qty.nil? ? ids.count : qty).each_with_index.map{|id, n| {
39
- type: "countries",
40
- id: Integer(id),
41
- attributes: {
42
- "name": names[n],
43
- "alpha3": alpha3(names[n]),
44
- "fetched-at": T2Airtime::Util.format_time(ts)
45
- },
46
- relationships: {
47
- operators: {
48
- links: {
49
- related: "/countries/#{id}/operators"
50
- }
51
- }
52
- }
53
- }}.as_json
54
- end
55
-
56
- def self.normalize(name)
57
- name.starts_with?("St") ? name.gsub("St", "Saint") : name
58
- end
59
-
60
- def self.alpha3(name)
61
- alpha3 = ISO3166::Country.find_country_by_name(name).try(:alpha3)
62
- unless alpha3
63
- alpha3 = case name
64
- when 'Saint Vincent Grenadines'
65
- 'VCT';
66
- when 'Kosovo'
67
- 'UNK'
68
- when 'Netherlands Antilles'
69
- 'ANT'
70
- when 'Serbia and Montenegro'
71
- 'SCG'
72
- end
73
- register_alpha3(alpha3, name) if %w(VCT UNK ANT SCG).include?(alpha3)
74
- end
75
- alpha3 || "XXX"
76
- end
77
-
78
- def self.register_alpha3(alpha3, name)
79
- ISO3166::Data.register(
80
- alpha2: 'XX',
81
- alpha3: alpha3,
82
- name: name
83
- )
84
- end
85
-
86
- end
87
-
88
- class Operator
89
-
90
- def self.take(country_qty=1, qty=5)
91
- countries = T2Airtime::Country.take(country_qty).shuffle
92
- unless countries.empty?
93
- countries.flat_map{|country| (
94
- reply = T2Airtime::API.api.operator_list(country["id"])
95
- reply.success? ? serialize(reply.data, reply.headers[:date], qty) : []
96
- )}
97
- end
98
- end
99
-
100
- def self.serialize(data, ts="#{Time.zone.now}", qty=nil)
101
- return [] if data[:operator].nil?
102
- names = data[:operator].split(",")
103
- ids = data[:operatorid].split(",")
104
- ids.take(qty.nil? ? ids.count : qty).each_with_index.map{|id, n| {
105
- type: "operators",
106
- id: Integer(id),
107
- attributes: {
108
- "name": names[n],
109
- "fetched-at": T2Airtime::Util.format_time(ts)
110
- },
111
- links: {
112
- logo: T2Airtime::Util.operator_logo_url(id)
113
- },
114
- relationships: {
115
- country: {
116
- data: {
117
- type: "countries",
118
- id: Integer(data[:countryid])
119
- }
120
- },
121
- products: {
122
- links: {
123
- related: "/countries/#{data[:countryid]}/operators/#{id}/products"
124
- }
125
- }
126
- },
127
- included: [
128
- {
129
- type: "countries",
130
- id: Integer(data[:countryid]),
131
- attributes: {
132
- "name": data[:country],
133
- "alpha3": T2Airtime::Country.alpha3(data[:country])
134
- }
135
- }
136
- ]
137
- }}.as_json
138
- end
139
-
140
- end
141
-
142
- class Product
143
-
144
- def self.take(operator_qty=1, qty=5)
145
- operators = T2Airtime::Operator.take(operator_qty).shuffle
146
- unless operators.empty?
147
- operators.flat_map{|operator| (
148
- reply = T2Airtime::API.api.product_list(operator["id"])
149
- reply.success? ? serialize(reply.data, reply.headers[:date], qty) : []
150
- )}
151
- end
152
- end
153
-
154
- def self.serialize(data, ts="#{Time.zone.now}", qty=nil)
155
- return [] if data[:product_list].nil?
156
- ids = data[:product_list].split(",")
157
- retail_prices = data[:retail_price_list].split(",")
158
- wholesale_prices = data[:wholesale_price_list].split(",")
159
- ids.take(qty.nil? ? ids.count : qty).each_with_index.map{|id, n| {
160
- type: "products",
161
- id: Integer(id),
162
- attributes: {
163
- "name": "#{id}#{data[:destination_currency]}",
164
- "currency": data[:destination_currency],
165
- "local-price": Float(id),
166
- "retail-price": Float(retail_prices[n]),
167
- "wholesale-price": Float(wholesale_prices[n]),
168
- "fetched-at": T2Airtime::Util.format_time(ts)
169
- },
170
- relationships: {
171
- country: {
172
- data: {
173
- type: "countries",
174
- id: Integer(data[:countryid])
175
- }
176
- },
177
- operator: {
178
- data: {
179
- type: "operators",
180
- id: Integer(data[:operatorid])
181
- }
182
- }
183
- },
184
- included: [
185
- {
186
- type: "countries",
187
- id: Integer(data[:countryid]),
188
- attributes: {
189
- "name": data[:country],
190
- "alpha3": T2Airtime::Country.alpha3(data[:country])
191
- }
192
- },
193
- {
194
- type: "operators",
195
- id: Integer(data[:operatorid]),
196
- attributes: {
197
- "name": data[:operator]
198
- },
199
- links: {
200
- logo: T2Airtime::Util.operator_logo_url(data[:operatorid])
201
- }
202
- }
203
- ]
204
- }}.as_json
205
- end
206
-
207
- end
208
-
209
- class Transaction
210
-
211
- def self.take(start=(Time.now-24.hours), stop=Time.now, msisdn=nil, destination=nil, code=nil, qty=5)
212
- reply = T2Airtime::API.api.transaction_list(start, stop, msisdn, destination, code)
213
- reply.success? ? serialize(reply.data, qty) : []
214
- end
215
-
216
- def self.serialize(data, qty=nil)
217
- return [] if data[:transaction_list].nil?
218
- ids = data[:transaction_list].split(",")
219
- ids.take(qty.nil? ? ids.count : qty).each.map{ |id| show(id) }
220
- end
221
-
222
-
223
- def self.show(id)
224
- reply = T2Airtime::API.api.transaction_info(id)
225
- reply.success? ? serialize_one(reply.data, reply.headers[:date]) : {}
226
- end
227
-
228
- def self.serialize_one(data, ts="#{Time.zone.now}")
229
- {
230
- type: "transactions",
231
- id: Integer(data[:transactionid]),
232
- attributes: {
233
- "msisdn": data[:msisdn],
234
- "destination-msisdn": data[:destination_msisdn],
235
- "transaction-authentication-key": data[:transaction_authentication_key],
236
- "transaction-error-code": Integer(data[:transaction_error_code]),
237
- "transaction-error-txt": data[:transaction_error_txt],
238
- "reference-operator": data[:reference_operator],
239
- "actual-product-sent": data[:actual_product_sent],
240
- "sms": data[:sms],
241
- "cid1": data[:cid1],
242
- "cid2": data[:cid2],
243
- "cid3": data[:cid3],
244
- "date": data[:date],
245
- "originating-currency": data[:originating_currency],
246
- "destination-currency": data[:destination_currency],
247
- "pin-based": data[:pin_based],
248
- "local-info-amount": data[:local_info_amount],
249
- "local-info-currency": data[:local_info_currency],
250
- "local-info-value": data[:local_info_value],
251
- "error-code": data[:error_code],
252
- "error-txt": data[:error_txt],
253
- "fetched-at": T2Airtime::Util.format_time(ts)
254
- },
255
- relationships: {
256
- country: {
257
- data: {
258
- type: "countries",
259
- id: Integer(data[:countryid])
260
- }
261
- },
262
- operator: {
263
- data: {
264
- type: "operators",
265
- id: Integer(data[:operatorid])
266
- }
267
- },
268
- product: {
269
- data: {
270
- type: "products",
271
- id: Integer(data[:product_requested])
272
- }
273
- }
274
- },
275
- included: [
276
- {
277
- type: "countries",
278
- id: Integer(data[:countryid]),
279
- attributes: {
280
- "name": data[:country],
281
- "alpha3": T2Airtime::Country.alpha3(data[:country])
282
- }
283
- },
284
- {
285
- type: "operators",
286
- id: Integer(data[:operatorid]),
287
- attributes: {
288
- "name": data[:operator]
289
- },
290
- links: {
291
- logo: T2Airtime::Util.operator_logo_url(data[:operatorid])
292
- }
293
- },
294
- {
295
- type: "products",
296
- id: Integer(data[:product_requested]),
297
- attributes: {
298
- "name": "#{data[:product_requested]}#{data[:destination_currency]}",
299
- "currency": data[:destination_currency],
300
- "wholesale-price": data[:wholesale_price],
301
- "retail-price": data[:retail_price],
302
- "local-price": Float(data[:product_requested])
303
- }
304
- }
305
- ]
306
- }.as_json
307
- end
308
-
309
-
310
- end
311
-
312
-
313
- end
1
+ module T2Airtime
2
+ class Account
3
+ def self.get
4
+ Rails.cache.fetch('accounts', expires_in: 1.hour) do
5
+ T2Airtime::API.api.account_info
6
+ end
7
+ end
8
+
9
+ def self.currency
10
+ Rails.cache.fetch('accounts/currency', expires_in: 24.hours) do
11
+ serialize(get.data)["attributes"]["currency"]
12
+ end
13
+ end
14
+
15
+ def self.info
16
+ get.success? ? serialize(get.data, get.headers[:date]) : []
17
+ end
18
+
19
+ def self.serialize(data, ts = Time.zone.now.to_s)
20
+ {
21
+ type: 'accounts',
22
+ id: T2Airtime::API.api.user,
23
+ attributes: {
24
+ type: data[:type],
25
+ name: data[:name],
26
+ currency: data[:currency],
27
+ balance: Float(data[:balance]),
28
+ wallet: Float(data[:wallet]),
29
+ fetchedAt: T2Airtime::Util.format_time(ts)
30
+ }
31
+ }
32
+ end
33
+ end
34
+
35
+ class Country
36
+ def self.all
37
+ Rails.cache.fetch('countries', expires_in: 1.hour) do
38
+ T2Airtime::API.api.country_list
39
+ end
40
+ end
41
+
42
+ def self.take(qty = 5)
43
+ countries = all
44
+ countries.success? ? serialize(countries.data, countries.headers[:date], qty) : []
45
+ end
46
+
47
+ def self.serialize(data, ts = Time.zone.now.to_s, qty = nil)
48
+ return [] if data[:countryid].nil?
49
+ names = data[:country].split(',')
50
+ ids = data[:countryid].split(',')
51
+ Rails.cache.fetch('countries/serializer', expires_in: 1.hour) do
52
+ ids.take(qty.nil? ? ids.count : qty).each_with_index.map do |id, n|
53
+ {
54
+ type: 'countries',
55
+ id: Integer(id),
56
+ attributes: {
57
+ name: names[n],
58
+ alpha3: alpha3(names[n]),
59
+ fetchedAt: T2Airtime::Util.format_time(ts)
60
+ }
61
+ }
62
+ end
63
+ end
64
+ end
65
+
66
+ def self.normalize(name)
67
+ name.starts_with?('St') ? name.gsub('St', 'Saint') : name
68
+ end
69
+
70
+ def self.alpha3(name)
71
+ alpha3 = ISO3166::Country.find_country_by_name(name).try(:alpha3)
72
+ unless alpha3
73
+ alpha3 = case name
74
+ when 'Saint Vincent Grenadines'
75
+ 'VCT'
76
+ when 'Kosovo'
77
+ 'UNK'
78
+ when 'Netherlands Antilles'
79
+ 'ANT'
80
+ when 'Serbia and Montenegro'
81
+ 'SCG'
82
+ end
83
+ register_alpha3(alpha3, name) if %w[VCT UNK ANT SCG].include?(alpha3)
84
+ end
85
+ alpha3 || 'XXX'
86
+ end
87
+
88
+ def self.register_alpha3(alpha3, name)
89
+ ISO3166::Data.register(
90
+ alpha2: 'XX',
91
+ alpha3: alpha3,
92
+ name: name
93
+ )
94
+ end
95
+ end
96
+
97
+ class Operator
98
+ def self.all(country_id)
99
+ Rails.cache.fetch("operators/#{country_id}", expires_in: 1.hour) do
100
+ T2Airtime::API.api.operator_list(country_id)
101
+ end
102
+ end
103
+
104
+ def self.take(country_qty = 1, qty = 5)
105
+ countries = T2Airtime::Country.take(country_qty).shuffle
106
+ unless countries.empty?
107
+ countries.flat_map do |country| (
108
+ operators = all(country['id'])
109
+ operators.success? ? serialize(operators.data, operators.headers[:date], qty) : []
110
+ )
111
+ end
112
+ end
113
+ end
114
+
115
+ def self.serialize(data, ts = Time.zone.now.to_s, qty = nil)
116
+ return [] if data[:operator].nil?
117
+ names = data[:operator].split(',')
118
+ ids = data[:operatorid].split(',')
119
+ Rails.cache.fetch("operators/#{data[:countryid]}/serializer", expires_in: 1.hour) do
120
+ ids.take(qty.nil? ? ids.count : qty).each_with_index.map do |id, n|
121
+ {
122
+ type: 'operators',
123
+ id: Integer(id),
124
+ attributes: {
125
+ name: names[n],
126
+ logo: T2Airtime::Util.operator_logo_url(id),
127
+ countryId: Integer(data[:countryid]),
128
+ countryName: data[:country],
129
+ countryAlpha3: T2Airtime::Country.alpha3(data[:country]),
130
+ fetchedAt: T2Airtime::Util.format_time(ts)
131
+ },
132
+ relationships: {
133
+ country: {
134
+ data: {
135
+ type: 'countries',
136
+ id: Integer(data[:countryid])
137
+ }
138
+ }
139
+ }
140
+ }
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ class Product
147
+ def self.all(operator_id)
148
+ Rails.cache.fetch("products/#{operator_id}", expires_in: 1.hour) do
149
+ T2Airtime::API.api.product_list(operator_id)
150
+ end
151
+ end
152
+
153
+ def self.take(operator_qty = 1, qty = 5)
154
+ operators = T2Airtime::Operator.take(operator_qty).shuffle
155
+ unless operators.empty?
156
+ operators.flat_map do |operator| (
157
+
158
+
159
+ products = all(operator['id'])
160
+ products.success? ? serialize(products.data, products.headers[:date], qty) : []
161
+ )
162
+ end
163
+ end
164
+ end
165
+
166
+ def self.serialize(data, ts = Time.zone.now.to_s, qty = nil)
167
+ return [] if data[:product_list].nil?
168
+ ids = data[:product_list].split(',')
169
+ retail_prices = data[:retail_price_list].split(',')
170
+ wholesale_prices = data[:wholesale_price_list].split(',')
171
+ Rails.cache.fetch("products/#{data[:operatorid]}/serializer", expires_in: 1.hour) do
172
+ ids.take(qty.nil? ? ids.count : qty).each_with_index.map do |id, n|
173
+ {
174
+ type: 'products',
175
+ id: Integer(id),
176
+ attributes: {
177
+ name: "#{Money.new(Integer(id) * 100, data[:destination_currency]).format}",
178
+ localCurrency: data[:destination_currency],
179
+ localCurrencySymbol: Money::Currency.new(data[:destination_currency]).symbol,
180
+ currency: Account.currency,
181
+ currencySymbol: Money::Currency.new(Account.currency).symbol,
182
+ localPrice: Float(id),
183
+ retailPrice: Float(retail_prices[n]),
184
+ wholesalePrice: Float(wholesale_prices[n]),
185
+ countryId: Integer(data[:countryid]),
186
+ countryName: data[:country],
187
+ countryAlpha3: T2Airtime::Country.alpha3(data[:country]),
188
+ operatorId: Integer(data[:operatorid]),
189
+ operatorName: data[:operator],
190
+ operatorLogo: T2Airtime::Util.operator_logo_url(data[:operatorid]),
191
+ fetchedAt: T2Airtime::Util.format_time(ts)
192
+ },
193
+ relationships: {
194
+ country: {
195
+ data: {
196
+ type: 'countries',
197
+ id: Integer(data[:countryid])
198
+ }
199
+ },
200
+ operator: {
201
+ data: {
202
+ type: 'operators',
203
+ id: Integer(data[:operatorid])
204
+ }
205
+ }
206
+ }
207
+ }
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ class Transaction
214
+ def self.take(start = (Time.now - 24.hours), stop = Time.now, msisdn = nil, destination = nil, code = nil, qty = 5)
215
+ reply = T2Airtime::API.api.transaction_list(start, stop, msisdn, destination, code)
216
+ reply.success? ? serialize(reply.data, qty) : []
217
+ end
218
+
219
+ def self.serialize(data, qty = nil)
220
+ return [] if data[:transaction_list].nil?
221
+ ids = data[:transaction_list].split(',')
222
+ ids.take(qty.nil? ? ids.count : qty).each.map { |id| show(id) }
223
+ end
224
+
225
+ def self.show(id)
226
+ reply = T2Airtime::API.api.transaction_info(id)
227
+ reply.success? ? serialize_one(reply.data, reply.headers[:date]) : {}
228
+ end
229
+
230
+ def self.serialize_one(data, ts = Time.zone.now.to_s)
231
+ {
232
+ type: 'transactions',
233
+ id: Integer(data[:transactionid]),
234
+ attributes: {
235
+ msisdn: data[:msisdn],
236
+ destinationMsisdn: data[:destination_msisdn],
237
+ transactionAuthenticationKey: data[:transaction_authentication_key],
238
+ transactionErrorCode: Integer(data[:transaction_error_code]),
239
+ transactionErrorTxt: data[:transaction_error_txt],
240
+ referenceOperator: data[:reference_operator],
241
+ actualProductSent: data[:actual_product_sent],
242
+ sms: data[:sms],
243
+ cid1: data[:cid1],
244
+ cid2: data[:cid2],
245
+ cid3: data[:cid3],
246
+ date: data[:date],
247
+ currency: data[:originating_currency],
248
+ localCurrency: data[:destination_currency],
249
+ pinBased: data[:pin_based],
250
+ localInfoAmount: data[:local_info_amount],
251
+ localInfoCurrency: data[:local_info_currency],
252
+ localInfoValue: data[:local_info_value],
253
+ errorCode: data[:error_code],
254
+ errorTxt: data[:error_txt],
255
+ countryId: Integer(data[:countryid]),
256
+ countryName: data[:country],
257
+ countryAlpha3: T2Airtime::Country.alpha3(data[:country]),
258
+ operatorId: Integer(data[:operatorid]),
259
+ operatorName: data[:operator],
260
+ operatorLogo: T2Airtime::Util.operator_logo_url(data[:operatorid]),
261
+ productName: "#{Money.new(Integer(data[:product_requested]) * 100, data[:destination_currency]).format}",
262
+ productLocalCurrency: data[:destination_currency],
263
+ productLocalCurrencySymbol: Money::Currency.new(data[:destination_currency]).symbol,
264
+ productCurrency: Account.currency,
265
+ productCurrencySymbol: Money::Currency.new(Account.currency).symbol,
266
+ productLocalPrice: Float(data[:product_requested]),
267
+ productRetailPrice: Float(data[:retail_price]),
268
+ productWholesalePrice: Float(data[:wholesale_price]),
269
+ fetchedAt: T2Airtime::Util.format_time(ts)
270
+ },
271
+ relationships: {
272
+ country: {
273
+ data: {
274
+ type: 'countries',
275
+ id: Integer(data[:countryid])
276
+ }
277
+ },
278
+ operator: {
279
+ data: {
280
+ type: 'operators',
281
+ id: Integer(data[:operatorid])
282
+ }
283
+ },
284
+ product: {
285
+ data: {
286
+ type: 'products',
287
+ id: Integer(data[:product_requested])
288
+ }
289
+ }
290
+ }
291
+ }
292
+ end
293
+ end
294
+ end
@@ -1,6 +1,6 @@
1
- module T2Airtime
2
- DOMAIN = "transferto.com"
3
- AIRTIME_DN = "airtime"
4
- OPLOGO_DN = "operator-logo"
5
- ENDPOINT = "cgi-bin/shop/topup"
6
- end
1
+ module T2Airtime
2
+ DOMAIN = 'transferto.com'.freeze
3
+ AIRTIME_DN = 'airtime'.freeze
4
+ OPLOGO_DN = 'operator-logo'.freeze
5
+ ENDPOINT = 'cgi-bin/shop/topup'.freeze
6
+ end