paymentrails-zero 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/lib/paymentrails/Balance.rb +4 -0
  4. data/lib/paymentrails/Batch.rb +20 -0
  5. data/lib/paymentrails/BatchSummary.rb +21 -0
  6. data/lib/paymentrails/Client.rb +100 -0
  7. data/lib/paymentrails/Configuration.rb +48 -0
  8. data/lib/paymentrails/Exceptions.rb +19 -0
  9. data/lib/paymentrails/Gateway.rb +43 -0
  10. data/lib/paymentrails/Invoice.rb +22 -0
  11. data/lib/paymentrails/InvoicePayment.rb +13 -0
  12. data/lib/paymentrails/OfflinePayment.rb +23 -0
  13. data/lib/paymentrails/Payment.rb +52 -0
  14. data/lib/paymentrails/Recipient.rb +44 -0
  15. data/lib/paymentrails/RecipientAccount.rb +30 -0
  16. data/lib/paymentrails/gateways/BalanceGateway.rb +15 -0
  17. data/lib/paymentrails/gateways/BatchGateway.rb +88 -0
  18. data/lib/paymentrails/gateways/GatewayHelper.rb +16 -0
  19. data/lib/paymentrails/gateways/InvoiceGateway.rb +77 -0
  20. data/lib/paymentrails/gateways/InvoicePaymentGateway.rb +56 -0
  21. data/lib/paymentrails/gateways/OfflinePaymentGateway.rb +61 -0
  22. data/lib/paymentrails/gateways/PaymentGateway.rb +61 -0
  23. data/lib/paymentrails/gateways/RecipientAccountGateway.rb +61 -0
  24. data/lib/paymentrails/gateways/RecipientGateway.rb +68 -0
  25. data/lib/paymentrails.rb +28 -0
  26. data/paymentrails.gemspec +18 -0
  27. data/spec/integration/BatchTest.rb +121 -0
  28. data/spec/integration/InvoicePaymentTest.rb +99 -0
  29. data/spec/integration/InvoiceTest.rb +124 -0
  30. data/spec/integration/RecipientTest.rb +91 -0
  31. data/spec/integration/helper.rb +4 -0
  32. data/spec/unit/ConfigurationTest.rb +51 -0
  33. data/spec/unit/PaymentRailsTest.rb +15 -0
  34. metadata +131 -0
@@ -0,0 +1,56 @@
1
+ require_relative '../Client.rb'
2
+ require_relative 'GatewayHelper'
3
+
4
+ module PaymentRails
5
+ class InvoicePaymentGateway
6
+ include GatewayHelper
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def create(body)
13
+ response = @client.post('/v1/invoices/payment/create', body)
14
+ invoice_payment_builder(response)
15
+ end
16
+
17
+ def update(body)
18
+ @client.post('/v1/invoices/payment/update', body)
19
+ true
20
+ end
21
+
22
+ def delete(body)
23
+ @client.post('/v1/invoices/payment/delete', body)
24
+ true
25
+ end
26
+
27
+ def search(body)
28
+ response = @client.post('/v1/invoices/payment/search', body)
29
+ invoice_payments_list_builder(response)
30
+ end
31
+
32
+ def invoice_payment_builder(response)
33
+ invoice_payment = InvoicePayment.new
34
+ data = JSON.parse(response)
35
+ data.each do |key, value|
36
+ next unless key === 'invoicePayment'
37
+ loosely_hydrate_model(invoice_payment, value)
38
+ end
39
+ invoice_payment
40
+ end
41
+
42
+ def invoice_payments_list_builder(response)
43
+ invoice_payments = []
44
+ data = JSON.parse(response)
45
+
46
+ data.each do |key, value|
47
+ next unless key === 'invoicePayments'
48
+ value.each do |newKey, _newValue|
49
+ invoice_payment = loosely_hydrate_model(InvoicePayment.new, newKey)
50
+ invoice_payments.push(invoice_payment)
51
+ end
52
+ end
53
+ invoice_payments
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../Client.rb'
2
+ require_relative 'GatewayHelper'
3
+
4
+ module PaymentRails
5
+ class OfflinePaymentGateway
6
+ include GatewayHelper
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def create(recipient_id, body)
13
+ response = @client.post('/v1/recipients/' + recipient_id + '/offlinePayments', body)
14
+ offline_payment_builder(response)
15
+ end
16
+
17
+ def update(recipient_id, offline_payment_id, body)
18
+ @client.patch('/v1/recipients/' + recipient_id + '/offlinePayments/' + offline_payment_id, body)
19
+ true
20
+ end
21
+
22
+ def delete(recipient_id, offline_payment_id)
23
+ @client.delete('/v1/recipients/' + recipient_id + '/offlinePayments/' + offline_payment_id)
24
+ true
25
+ end
26
+
27
+ def search(recipient_id = '', page = 1, page_size = 10, term = '')
28
+ if recipient_id === ''
29
+ response = @client.get('/v1/offline-payments?page=' + page.to_s + '&pageSize=' + page_size.to_s + '&search=' + term)
30
+ else
31
+ response = @client.get('/v1/recipients/' + recipient_id + '/offlinePayments?page=' + page.to_s + '&pageSize=' + page_size.to_s + '&search=' + term)
32
+ end
33
+
34
+ offline_payments_list_builder(response)
35
+ end
36
+
37
+ def offline_payment_builder(response)
38
+ offline_payment = OfflinePayment.new
39
+ data = JSON.parse(response)
40
+ data.each do |key, value|
41
+ next unless key === 'offlinePayment'
42
+ loosely_hydrate_model(offline_payment, value)
43
+ end
44
+ offline_payment
45
+ end
46
+
47
+ def offline_payments_list_builder(response)
48
+ offline_payments = []
49
+ data = JSON.parse(response)
50
+
51
+ data.each do |key, value|
52
+ next unless key === 'offlinePayments'
53
+ value.each do |newKey, _newValue|
54
+ offline_payment = loosely_hydrate_model(OfflinePayment.new, newKey)
55
+ offline_payments.push(offline_payment)
56
+ end
57
+ end
58
+ offline_payments
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../Client.rb'
2
+ require_relative 'GatewayHelper'
3
+
4
+ module PaymentRails
5
+ class PaymentGateway
6
+ include GatewayHelper
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(batch_id, payment_id)
13
+ response = @client.get('/v1/batches/' + batch_id + '/payments/' + payment_id)
14
+ payment_builder(response)
15
+ end
16
+
17
+ def create(batch_id, body)
18
+ response = @client.post('/v1/batches/' + batch_id + '/payments', body)
19
+ payment_builder(response)
20
+ end
21
+
22
+ def update(batch_id, payment_id, body)
23
+ @client.patch('/v1/batches/' + batch_id + '/payments/' + payment_id, body)
24
+ true
25
+ end
26
+
27
+ def delete(batch_id, payment_id)
28
+ @client.delete('/v1/batches/' + batch_id + '/payments/' + payment_id)
29
+ true
30
+ end
31
+
32
+ def search(batch_id, page = 1, page_size = 10, term = '')
33
+ response = @client.get('/v1/batches/' + batch_id.to_s + '/payments?page=' + page.to_s + '&pageSize=' + page_size.to_s + '&search=' + term)
34
+ payments_list_builder(response)
35
+ end
36
+
37
+ def payment_builder(response)
38
+ payment = Payment.new
39
+ data = JSON.parse(response)
40
+ data.each do |key, value|
41
+ next unless key === 'payment'
42
+ loosely_hydrate_model(payment, value)
43
+ end
44
+ payment
45
+ end
46
+
47
+ def payments_list_builder(response)
48
+ payments = []
49
+ data = JSON.parse(response)
50
+
51
+ data.each do |key, value|
52
+ next unless key === 'payments'
53
+ value.each do |newKey, _newValue|
54
+ payment = loosely_hydrate_model(Payment.new, newKey)
55
+ payments.push(payment)
56
+ end
57
+ end
58
+ payments
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ require_relative '../Client.rb'
2
+ require_relative 'GatewayHelper'
3
+
4
+ module PaymentRails
5
+ class RecipientAccountGateway
6
+ include GatewayHelper
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(recipient_id, recipient_account_id)
13
+ response = @client.get('/v1/recipients/' + recipient_id + '/accounts/' + recipient_account_id)
14
+ recipient_account_builder(response)
15
+ end
16
+
17
+ def all(recipient_id)
18
+ response = @client.get('/v1/recipients/' + recipient_id + '/accounts/')
19
+ recipient_account_list_builder(response)
20
+ end
21
+
22
+ def create(recipient_id, body)
23
+ response = @client.post('/v1/recipients/' + recipient_id + '/accounts', body)
24
+ recipient_account_builder(response)
25
+ end
26
+
27
+ def update(recipient_id, recipient_account_id, body)
28
+ response = @client.patch('/v1/recipients/' + recipient_id + '/accounts/' + recipient_account_id, body)
29
+ recipient_account_builder(response)
30
+ end
31
+
32
+ def delete(recipient_id, recipient_account_id)
33
+ @client.delete('/v1/recipients/' + recipient_id + '/accounts/' + recipient_account_id)
34
+ true
35
+ end
36
+
37
+ def recipient_account_builder(response)
38
+ recipient_account = RecipientAccount.new
39
+ data = JSON.parse(response)
40
+ data.each do |key, value|
41
+ next unless key === 'account'
42
+ loosely_hydrate_model(recipient_account, value)
43
+ end
44
+ recipient_account
45
+ end
46
+
47
+ def recipient_account_list_builder(response)
48
+ recipient_accounts = []
49
+ data = JSON.parse(response)
50
+
51
+ data.each do |key, value|
52
+ next unless key === 'accounts'
53
+ value.each do |newKey, _newValue|
54
+ recipient_account = loosely_hydrate_model(RecipientAccount.new, newKey)
55
+ recipient_accounts.push(recipient_account)
56
+ end
57
+ end
58
+ recipient_accounts
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,68 @@
1
+ require_relative '../Client.rb'
2
+ require_relative 'GatewayHelper'
3
+
4
+ module PaymentRails
5
+ class RecipientGateway
6
+ include GatewayHelper
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def find(recipient_id)
13
+ response = @client.get('/v1/recipients/' + recipient_id)
14
+ recipient_builder(response)
15
+ end
16
+
17
+ def create(body)
18
+ response = @client.post('/v1/recipients/', body)
19
+ recipient_builder(response)
20
+ end
21
+
22
+ def update(recipient_id, body)
23
+ @client.patch('/v1/recipients/' + recipient_id, body)
24
+ true
25
+ end
26
+
27
+ def delete(recipient_id)
28
+ @client.delete('/v1/recipients/' + recipient_id)
29
+ true
30
+ end
31
+
32
+ # TODO: if we can afford a breaking change ideally these should be kwargs
33
+ def search(page = 1, page_size = 10, prefix_search = '', filters = {})
34
+ query_string = URI.encode_www_form(
35
+ page: page.to_s,
36
+ pageSize: page_size.to_s,
37
+ search: prefix_search,
38
+ **filters
39
+ )
40
+ response = @client.get("/v1/recipients?#{query_string}")
41
+ recipient_list_builder(response)
42
+ end
43
+
44
+ def recipient_builder(response)
45
+ recipient = Recipient.new
46
+ data = JSON.parse(response)
47
+ data.each do |key, value|
48
+ next unless key === 'recipient'
49
+ loosely_hydrate_model(recipient, value)
50
+ end
51
+ recipient
52
+ end
53
+
54
+ def recipient_list_builder(response)
55
+ recipients = []
56
+ data = JSON.parse(response)
57
+
58
+ data.each do |key, value|
59
+ next unless key === 'recipients'
60
+ value.each do |newKey, _newValue|
61
+ recipient = loosely_hydrate_model(Recipient.new, newKey)
62
+ recipients.push(recipient)
63
+ end
64
+ end
65
+ recipients
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,28 @@
1
+ require 'paymentrails/Configuration'
2
+ require 'paymentrails/Gateway'
3
+
4
+ require 'paymentrails/gateways/BalanceGateway'
5
+ require 'paymentrails/gateways/BatchGateway'
6
+ require 'paymentrails/gateways/PaymentGateway'
7
+ require 'paymentrails/gateways/RecipientGateway'
8
+ require 'paymentrails/gateways/RecipientAccountGateway'
9
+ require 'paymentrails/gateways/OfflinePaymentGateway'
10
+ require 'paymentrails/gateways/InvoiceGateway'
11
+ require 'paymentrails/gateways/InvoicePaymentGateway'
12
+
13
+ require 'paymentrails/Balance'
14
+ require 'paymentrails/Batch'
15
+ require 'paymentrails/BatchSummary'
16
+ require 'paymentrails/Exceptions'
17
+ require 'paymentrails/Payment'
18
+ require 'paymentrails/Recipient'
19
+ require 'paymentrails/RecipientAccount'
20
+ require 'paymentrails/OfflinePayment'
21
+ require 'paymentrails/Invoice'
22
+ require 'paymentrails/InvoicePayment'
23
+
24
+ module PaymentRails
25
+ def self.client(key, secret, environment = 'production', **optionals)
26
+ Gateway.new(Configuration.new(key, secret, environment, **optionals))
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "paymentrails-zero"
5
+ s.summary = "Trolley Ruby SDK"
6
+ s.description = "Ruby SDK for interacting with the Trolley API"
7
+ s.version = '0.2.13'
8
+ s.homepage = 'https://trolley.com/'
9
+ s.email = ['developer-tools@trolley.com']
10
+ s.license = "MIT"
11
+ s.author = "PaymentRails"
12
+ s.files = Dir.glob ["README.rdoc", "LICENSE", "lib/**/*.{rb,crt}", "spec/**/*", "*.gemspec"]
13
+ s.required_ruby_version = '>= 2.4'
14
+ s.add_development_dependency 'dotenv', '~> 2'
15
+ s.add_development_dependency 'rake', '~> 12'
16
+ s.add_development_dependency "rubocop", '~> 0.77.0'
17
+ s.add_development_dependency 'test-unit', '~> 3'
18
+ end
@@ -0,0 +1,121 @@
1
+ require_relative 'helper'
2
+
3
+ class BatchTest < Test::Unit::TestCase
4
+ def setup
5
+ @client = PaymentRails.client(
6
+ ENV.fetch('SANDBOX_API_KEY'),
7
+ ENV.fetch('SANDBOX_SECRET_KEY'),
8
+ 'production',
9
+ proxy_uri: ENV['PROXY_URI']
10
+ )
11
+ end
12
+
13
+ def create_recipient
14
+ uuid = SecureRandom.uuid.to_s
15
+ recipient = @client.recipient.create(
16
+ type: 'individual',
17
+ firstName: 'Tom',
18
+ lastName: 'Jones',
19
+ email: 'test.batch' + uuid + '@example.com',
20
+ address: {
21
+ street1: '123 Wolfstrasse',
22
+ city: 'Berlin',
23
+ country: 'DE',
24
+ postalCode: '123123'
25
+ }
26
+ )
27
+ @client.recipient_account.create(recipient.id, type: 'bank-transfer', currency: 'EUR', country: 'DE', iban: 'DE89 3704 0044 0532 0130 00')
28
+ recipient
29
+ end
30
+
31
+ def test_create
32
+ batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
33
+ assert_not_nil(batch)
34
+ assert_not_nil(batch.id)
35
+
36
+ batch = @client.batch.all
37
+ assert_true(batch.count > 0)
38
+ end
39
+
40
+ def test_update
41
+ batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Create')
42
+ assert_not_nil(batch)
43
+ assert_not_nil(batch.id)
44
+
45
+ all = @client.batch.all
46
+ assert_true(all.count > 0)
47
+
48
+ response = @client.batch.update(batch.id, description: 'Integration Update')
49
+ assert_true(response)
50
+ findBatch = @client.batch.find(batch.id)
51
+ assert_equal('Integration Update', findBatch.description)
52
+ assert_equal('open', batch.status)
53
+
54
+ response = @client.batch.delete(batch.id)
55
+ assert_true(response)
56
+ end
57
+
58
+ def test_create_with_payments
59
+ recipientAlpha = create_recipient
60
+ recipientBeta = create_recipient
61
+
62
+ batch = @client.batch.create(
63
+ sourceCurrency: 'USD', description: 'Integration Test Payments', payments: [
64
+ { targetAmount: '10.00', targetCurrency: 'EUR', recipient: { id: recipientAlpha.id } },
65
+ { sourceAmount: '10.00', recipient: { id: recipientBeta.id } }
66
+ ]
67
+ )
68
+
69
+ assert_not_nil(batch)
70
+ assert_not_nil(batch.id)
71
+
72
+ findBatch = @client.batch.find(batch.id)
73
+ assert_not_nil(findBatch)
74
+ assert_equal(2, findBatch.totalPayments)
75
+
76
+ payments = @client.payment.search(batch.id)
77
+ payments.each { |item| assert_equal('pending', item.status) }
78
+ end
79
+
80
+ def test_payments
81
+ batch = @client.batch.create(sourceCurrency: 'USD', description: 'Integration Test Payments')
82
+ assert_not_nil(batch)
83
+ assert_not_nil(batch.id)
84
+
85
+ recipient = create_recipient
86
+
87
+ payment = @client.payment.create(batch.id, sourceAmount: '10.00', recipient: { id: recipient.id })
88
+
89
+ assert_not_nil(payment)
90
+ assert_not_nil(payment.id)
91
+
92
+ response = @client.payment.update(batch.id, payment.id, sourceAmount: '20.00')
93
+ assert_true(response)
94
+
95
+ response = @client.payment.delete(batch.id, payment.id)
96
+ assert_true(response)
97
+ end
98
+
99
+ def test_processing
100
+ recipientAlpha = create_recipient
101
+ recipientBeta = create_recipient
102
+
103
+ batch = @client.batch.create(
104
+ sourceCurrency: 'USD', description: 'Integration Test Payments', payments: [
105
+ { targetAmount: '10.00', targetCurrency: 'EUR', recipient: { id: recipientAlpha.id } },
106
+ { sourceAmount: '10.00', recipient: { id: recipientBeta.id } }
107
+ ]
108
+ )
109
+ assert_not_nil(batch)
110
+ assert_not_nil(batch.id)
111
+
112
+ summary = @client.batch.summary(batch.id)
113
+ assert_equal(2, summary.detail['bank-transfer']['count'])
114
+
115
+ quote = @client.batch.generate_quote(batch.id)
116
+ assert_not_nil(quote)
117
+
118
+ start = @client.batch.start_processing(batch.id)
119
+ assert_not_nil(start)
120
+ end
121
+ end
@@ -0,0 +1,99 @@
1
+ require_relative 'helper'
2
+
3
+ class InvoicePaymentTest < Test::Unit::TestCase
4
+ def setup
5
+ @client = PaymentRails.client(
6
+ ENV.fetch('SANDBOX_API_KEY'),
7
+ ENV.fetch('SANDBOX_SECRET_KEY'),
8
+ 'production',
9
+ proxy_uri: ENV['PROXY_URI']
10
+ )
11
+ end
12
+
13
+ def create_recipient
14
+ uuid = SecureRandom.uuid.to_s
15
+ recipient = @client.recipient.create(
16
+ type: 'individual',
17
+ firstName: 'Tom',
18
+ lastName: 'Jones',
19
+ email: 'test.batch' + uuid + '@example.com',
20
+ address: {
21
+ street1: '123 Wolfstrasse',
22
+ city: 'Berlin',
23
+ country: 'DE',
24
+ postalCode: '123123'
25
+ }
26
+ )
27
+ @client.recipient_account.create(recipient.id, type: 'bank-transfer', currency: 'EUR', country: 'DE', iban: 'DE89 3704 0044 0532 0130 00')
28
+ recipient
29
+ end
30
+
31
+ def test_create
32
+ recipient = create_recipient
33
+ invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
34
+ assert_not_nil(invoice)
35
+ assert_not_nil(invoice.id)
36
+ assert_equal('open', invoice.status)
37
+
38
+ invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
39
+ assert_not_nil(invoice_line.lines)
40
+ assert_not_nil(invoice_line.lines.first['id'])
41
+
42
+ @client.invoice_payment.create(ids: [invoiceId: invoice.id])
43
+ invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
44
+ assert_true(invoice_payments.count > 0)
45
+
46
+ findInvoice = @client.invoice.find(invoiceId: invoice.id)
47
+ assert_equal('paid', findInvoice.status)
48
+ end
49
+
50
+ def test_update
51
+ recipient = create_recipient
52
+
53
+ invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
54
+ assert_not_nil(invoice)
55
+ assert_not_nil(invoice.id)
56
+
57
+ invoices = @client.invoice.search({})
58
+ assert_true(invoices.count > 0)
59
+
60
+ invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
61
+ assert_not_nil(invoice_line.lines)
62
+ assert_not_nil(invoice_line.lines.first['id'])
63
+
64
+ invoice_payment = @client.invoice_payment.create(ids: [invoiceId: invoice.id])
65
+ invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
66
+ assert_true(invoice_payments.count > 0)
67
+ assert_equal('2000.00', invoice_payments.first.amount['value'])
68
+
69
+ response = @client.invoice_payment.update(paymentId: invoice_payment.paymentId, invoiceLineId: invoice_payment.invoicePayments.first['invoiceLineId'], amount: { value: '5000', currency: 'USD' })
70
+ assert_true(response)
71
+ invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
72
+ assert_true(invoice_payments.count > 0)
73
+ assert_equal('5000.00', invoice_payments.first.amount['value'])
74
+ end
75
+
76
+ def test_delete
77
+ recipient = create_recipient
78
+
79
+ invoice = @client.invoice.create(recipientId: recipient.id, description: 'Integration Test Invoice Create')
80
+ assert_not_nil(invoice)
81
+ assert_not_nil(invoice.id)
82
+
83
+ invoices = @client.invoice.search({})
84
+ assert_true(invoices.count > 0)
85
+
86
+ invoice_line = @client.invoice.create_line(invoiceId: invoice.id, lines: [{ unitAmount: { value: '2000', currency: 'USD' } }])
87
+ assert_not_nil(invoice_line.lines)
88
+ assert_not_nil(invoice_line.lines.first['id'])
89
+
90
+ invoice_payment = @client.invoice_payment.create(ids: [invoiceId: invoice.id])
91
+ invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
92
+ assert_true(invoice_payments.count > 0)
93
+
94
+ response = @client.invoice_payment.delete(paymentId: invoice_payment.paymentId, invoiceLineIds: [invoice_payment.invoicePayments.first['invoiceLineId']])
95
+ assert_true(response)
96
+ invoice_payments = @client.invoice_payment.search(invoiceIds: [invoice.id])
97
+ assert_true(invoice_payments.count == 0)
98
+ end
99
+ end