quaderno 1.17.1 → 2.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff20a4dbd47a968b4fedb922d622804909717069a0bcab8ebf077090fb3eff96
4
- data.tar.gz: 13b73cd944e916c59309ac000e4366cb718ef1a253fd4a2f83ede62a2ced5b85
3
+ metadata.gz: 5785e9a03af0c0ffa3eb2d52fc0586e8fa866c9da75170619a0a53755f2d2623
4
+ data.tar.gz: b45c9dbb82dc07b655dc3a8a3bb9a636fad5d1e3d5b1e15382fdeb4290c84357
5
5
  SHA512:
6
- metadata.gz: 8a8cd3b2fbab98cecb89e9e57a41bba5b85e5b088bce9c4ca7718a2942d3227225bf29828fb57bba4d3f85a5a0a8c72ba6c4ab11af3d08cdc0bca07bca0cdaba
7
- data.tar.gz: b5db04494e9c164d76e269c96409309f42925e993a39f78f8a7cdabe1a99b17abeee0af5dc950864a8dd2461f7192884a3699ce9a9f204eb234ce1694aea59fb
6
+ metadata.gz: fae563254f44fbd6a1128916bbc79d134b312a0945ad97b727b064140900e7d336499836b7eafd6f103d2a3b0cce5be5c410eb1e72043dfbea3b3eb7ec1bfdbb
7
+ data.tar.gz: fe5a981e7e7a2c3f48df1b83c0f9bf1cc87db36044d45cd998b2167940cc5401534750145617baa82fafc27b4511061a5468897cf9adfc7ee6ff5528068ab97f
@@ -0,0 +1,35 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ master ]
13
+ pull_request:
14
+ branches: [ master ]
15
+
16
+ jobs:
17
+ test:
18
+
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ matrix:
22
+ ruby-version: ['2.5', '2.6', '2.7', '3.0']
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
28
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
29
+ # uses: ruby/setup-ruby@v1
30
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
31
+ with:
32
+ ruby-version: ${{ matrix.ruby-version }}
33
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
34
+ - name: Run tests
35
+ run: bundle exec rspec ./spec/**/*.rb
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Quaderno-ruby is a ruby wrapper for [Quaderno API] (https://github.com/quaderno/quaderno-api).
4
4
 
5
- Current version is 1.17.0 See the changelog [here](https://github.com/quaderno/quaderno-ruby/blob/master/changelog.md)
5
+ Current version is 2.1.2 See the changelog [here](https://github.com/quaderno/quaderno-ruby/blob/master/changelog.md)
6
6
 
7
7
  ## Installation & Configuration
8
8
 
@@ -19,6 +19,7 @@ To configure just add this to your initializers
19
19
  config.auth_token = 'my_authenticate_token'
20
20
  config.url = 'https://my_subdomain.quadernoapp.com/api/'
21
21
  config.api_version = API_VERSION # Optional, defaults to the API version set in your account
22
+ config.user_agent_header = 'my custom user agent' # Optional, will make support for your account more efficient if you are doing oauth integrations
22
23
  end
23
24
  ```
24
25
 
@@ -99,10 +100,9 @@ Quaderno-ruby parses all the json responses in human readable data, so you can a
99
100
  ### Getting contacts
100
101
  ```ruby
101
102
  Quaderno::Contact.all #=> Array
102
- Quaderno::Contact.all(page: 1) #=> Array
103
103
  ```
104
104
 
105
- will return an array with all your contacts on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name. For example:
105
+ will return an array with all your contacts. You can also pass query strings using the attribute :q in order to filter the results by contact name. For example:
106
106
 
107
107
  ```ruby
108
108
  Quaderno::Contact.all(q: 'John Doe') #=> Array
@@ -188,10 +188,9 @@ will delete the item with the id passed as parameter. If the deletion was succe
188
188
  ### Getting invoices
189
189
  ```ruby
190
190
  Quaderno::Invoice.all #=> Array
191
- Quaderno::Invoice.all(page: 1) #=> Array
192
191
  ```
193
192
 
194
- will return an array with all your invoices on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
193
+ will return an array with all your invoices. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
195
194
 
196
195
  ### Finding an invoice
197
196
  ```ruby
@@ -259,67 +258,14 @@ In order to remove a payment you will need the Invoice instance you want to upd
259
258
  result.success #=> Boolean
260
259
  ```
261
260
 
262
- ## Managing receipts
263
-
264
- ### Getting receipts
265
- ```ruby
266
- Quaderno::Receipt.all #=> Array
267
- Quaderno::Receipt.all(page: 1) #=> Array
268
- ```
269
-
270
- will return an array with all your receipts on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
271
-
272
- ### Finding a receipt
273
- ```ruby
274
- Quaderno::Receipt.find(id) #=> Quaderno::Receipt
275
- ```
276
-
277
- will return the receipt with the id passed as parameter.
278
-
279
- ### Creating a new receipt
280
-
281
- ```ruby
282
- Quaderno::Receipt.create(params) #=> Quaderno::Receipt
283
- ```
284
-
285
- will create an receipt using the information of the hash passed as parameter.
286
-
287
- ### Updating an existing receipt
288
- ```ruby
289
- Quaderno::Receipt.update(id, params) #=> Quaderno::Receipt
290
- ```
291
-
292
- will update the specified receipt with the data of the hash passed as second parameter.
293
-
294
- ### Deleting an receipt
295
-
296
- ```ruby
297
- Quaderno::Receipt.delete(id) #=> Quaderno::Receipt
298
- ```
299
-
300
- will delete the receipt with the id passed as parameter. If the deletion was successful, an instance of `Quaderno::Receipt` with the `deleted` attribute set to `true` will be returned.
301
-
302
- ### Delivering the receipt
303
-
304
- In order to deliver the receipt to the default recipient you will need the receipt you want to send.
305
-
306
- ```ruby
307
- receipt = Quaderno::Receipt.find(receipt_id)
308
- result = receipt.deliver #=> Quaderno::Base
309
-
310
- result.success #=> Boolean
311
- ```
312
-
313
-
314
261
  ## Managing credits
315
262
 
316
263
  ### Getting credits
317
264
  ```ruby
318
265
  Quaderno::Credit.all #=> Array
319
- Quaderno::Credit.all(page: 1) #=> Array
320
266
  ```
321
267
 
322
- will return an array with all your credit notes on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
268
+ will return an array with all your credit notes. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
323
269
 
324
270
  ### Finding a credit
325
271
  ```ruby
@@ -337,10 +283,10 @@ will return the credit note with the transaction id passed as parameter.
337
283
  ### Creating a new credit
338
284
 
339
285
  ```ruby
340
- Quaderno::Credit.create(params) #=> Quaderno::Credit
286
+ Quaderno::Credit.create(invoice_id: 42) #=> Quaderno::Credit
341
287
  ```
342
288
 
343
- will create a credit using the information of the hash passed as parameter.
289
+ will create a credit from the invoice specified in the parameter.
344
290
 
345
291
  ### Updating an existing credit
346
292
  ```ruby
@@ -395,10 +341,9 @@ If the deletion was successful, an instance of `Quaderno::Payment` with the `del
395
341
  ### Getting estimates
396
342
  ```ruby
397
343
  Quaderno::Estimate.all #=> Array
398
- Quaderno::Estimate.all(page: 1) #=> Array
399
344
  ```
400
345
 
401
- will return an array with all your estimates on the first page.
346
+ will return an array with all your estimates.
402
347
 
403
348
  ### Finding an estimate
404
349
  ```ruby
@@ -464,10 +409,9 @@ In order to remove a payment you will need the estimate you want to update.
464
409
  ### Getting expenses
465
410
  ```ruby
466
411
  Quaderno::Expense.all #=> Array
467
- Quaderno::Expense.all(page: 1) #=> Array
468
412
  ```
469
413
 
470
- will return an array with all your expenses on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date.
414
+ will return an array with all your expenses. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date.
471
415
 
472
416
  ### Finding an expense
473
417
  ```ruby
@@ -503,10 +447,9 @@ will delete the expense with the id passed as parameter. If the deletion was suc
503
447
  ### Getting recurrings
504
448
  ```ruby
505
449
  Quaderno::Recurring.all #=> Array
506
- Quaderno::Recurring.all(page: 1) #=> Array
507
450
  ```
508
451
 
509
- will return an array with all your recurring notes on the first page. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
452
+ will return an array with all your recurring notes. You can also pass query strings using the attribute :q in order to filter the results by contact name, :state to filter by state or :date to filter by date
510
453
 
511
454
  ### Finding a recurring
512
455
  ```ruby
@@ -585,17 +528,17 @@ will delete the webhook with the id passed as parameter. If the deletion was suc
585
528
 
586
529
  will calculate the taxes applied for a customer based on the data pased as parameters.
587
530
 
588
- ### Validate VAT numbers
531
+ ### Validate tax ID
589
532
  ```ruby
590
533
  country = 'IE'
591
- vat_number = 'IE6388047V'
534
+ tax_id = 'IE6388047V'
592
535
 
593
- result = Quaderno::Tax.validate_vat_number(country, vat_number) #=> Quaderno::Tax
536
+ result = Quaderno::Tax.validate_tax_id(country, tax_id) #=> Quaderno::Tax
594
537
 
595
538
  result.valid #=> Boolean or nil
596
539
  ```
597
540
 
598
- will validate the vat number for the passed country.
541
+ will validate the tax ID or business number for the specified country.
599
542
 
600
543
  ## Evidences
601
544
 
@@ -642,6 +585,29 @@ will update the specified checkout session with the data of the hash passed as s
642
585
  ```
643
586
  will delete the checkout session with the id passed as parameter. If the deletion was successful, an instance of `Quaderno::CheckoutSession` with the `deleted` attribute set to `true` will be returned.
644
587
 
588
+ ## Managing report requests
589
+
590
+ ### Getting report requests
591
+ ```ruby
592
+ Quaderno::ReportRequest.all #=> Array
593
+ ```
594
+
595
+ will return an array with all your report requests.
596
+
597
+ ### Finding a report request
598
+ ```ruby
599
+ Quaderno::ReportRequest.find(id) #=> Quaderno::ReportRequest
600
+ ```
601
+
602
+ will return the report request with the id passed as parameter.
603
+
604
+ ### Creating a new report request
605
+
606
+ ```ruby
607
+ Quaderno::ReportRequest.create(params) #=> Quaderno::ReportRequest
608
+ ```
609
+
610
+ will create a report request using the information of the hash passed as parameter and return an instance of Quaderno::ReportRequest with the created report request.
645
611
 
646
612
  ## Exceptions
647
613
  Quaderno-ruby exceptions raise depending on the type of error:
@@ -661,6 +627,7 @@ Quaderno-ruby exceptions raise depending on the type of error:
661
627
 
662
628
  Quaderno::Exceptions::RequiredFieldsEmptyOrInvalid # Raised if the format of the request is right but some validations failed. You can JSON parse the exception message to get which field triggered the exception. For example: '{"errors":{"vat_number":["is not a valid German vat number"]}}'
663
629
 
630
+ Quaderno::Exceptions::ServerError # Raised when Quaderno returns an HTTP response code of the 50X family. Try again later or contact support if the issue persists
664
631
  ```
665
632
 
666
633
  All those exceptions inherit from `Quaderno::Exceptions::BaseException`.
@@ -669,12 +636,27 @@ All those exceptions inherit from `Quaderno::Exceptions::BaseException`.
669
636
  Whenever you call the `all` method on one of the classes, the result will be a `Quaderno::Collection`. For example:
670
637
 
671
638
  ```ruby
672
- collection = Quaderno::Contact.all(page: 2)
639
+ collection = Quaderno::Contact.all
673
640
 
674
641
  collection.class #=> Quaderno::Collection
675
- collection.pagination_info #=> {:current_page=>"1", :total_pages=>"3"}
676
- collection.current_page #=> "2"
677
- collection.total_pages #=> "3"
642
+ collection.has_more? #=> true
643
+ collection.next_page #=> another instance of
644
+ ```
645
+
646
+ The `next_page` method is an abstraction for the `created_before` parameter, which you may also use with the `all` method.
647
+
648
+ ```ruby
649
+ collection = Quaderno::Contact.all
650
+
651
+ Quaderno::Contact.all(created_before: collection.last.id)
652
+ ```
653
+
654
+ You can also use the `limit` parameter to determine how many results to retrieve. Its default is `25`, and Quaderno will cap the limit at `100`.
655
+
656
+ ```ruby
657
+ collection = Quaderno::Contact.all(limit: 50)
658
+
659
+ collection.length #=> 50
678
660
  ```
679
661
 
680
662
  ### Thread-safe configuration
@@ -731,5 +713,3 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
731
713
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
732
714
 
733
715
  THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
734
-
735
-
data/changelog.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.1.2
4
+ * Fixed a reference to non-existent variable by [**@fwitzke**](https://github.com/fwitzke)
5
+ ## 2.1.1
6
+ * Added assign operator to the user_agent_header
7
+
8
+ ## 2.1.0
9
+ * Added a new `Quaderno::Exceptions::ServerError` exception for more transparency, and better control of workflows
10
+ * Added a `user_agent_header` optional configuration to make debugging oauth integrations easier
11
+
12
+ ## 2.0.2
13
+ * Fix an issue with the parameters sent during the `validate_vat_number` request
14
+ * Renames `validate_vat_number` into `validate_tax_id`
15
+
16
+ ## 2.0.1
17
+ * Fix an issue where requests would result in an error due to a missing `require`
18
+
19
+ ## 2.0.0
20
+ * **Breaking change** Pagination strategy has been updated to be cursor based. Collections no longer offer the `current_page` and `total_pages` methods, and offer `has_more?` and `next_page` instead. The `page` parameter is no longer supported either, in favour of the `created_before` parameter. [See more information in the documentation](https://developers.quaderno.io/api/#pagination).
21
+ * **Breaking change** `Quaderno::Tax.calculate` uses the [new tax calculation endpoint](https://developers.quaderno.io/api/#calculate-a-tax-rate). This endpoint accepts address parameters with the prefix `to_`. For example, `postal_code` is deprecated in favour of `to_postal_code`.
22
+ * `Quaderno::Tax.validate` uses the [new tax ID validation endpoint](https://developers.quaderno.io/api/#validate-a-tax-id). The signature did not change, and no updates are necessary.
23
+ * All requests now send the gem version in their User Agent header.
24
+
3
25
  ## 1.17.1
4
26
  * Do not modify the input arguments when the thread-safe mode is used.
5
27
 
@@ -15,6 +15,7 @@ class Quaderno::Base < OpenStruct
15
15
  @@rate_limit_info = nil
16
16
  @@api_version = nil
17
17
  @@url = PRODUCTION_URL
18
+ @@user_agent_suffix = nil
18
19
 
19
20
  # Class methods
20
21
  def self.api_model(klass)
@@ -46,16 +47,22 @@ class Quaderno::Base < OpenStruct
46
47
  @@url = url
47
48
  end
48
49
 
50
+ def self.user_agent_header=(custom_user_agent)
51
+ @@user_agent_suffix = custom_user_agent
52
+ end
53
+
49
54
  def self.authorization(auth_token, mode = nil)
50
55
  mode ||= :production
51
56
  url = mode == :sandbox ? SANDBOX_URL : PRODUCTION_URL
52
- response = get("#{url}authorization.json", basic_auth: { username: auth_token }, headers: version_header)
57
+ response = get("#{url}authorization.json", basic_auth: { username: auth_token }, headers: default_headers)
53
58
 
54
59
  if response.code == 200
55
60
  data = self.new(response.parsed_response)
56
61
  data.rate_limit_info = response
57
62
 
58
63
  data
64
+ elsif response.response.is_a?(Net::HTTPServerError)
65
+ raise_exception(Quaderno::Exceptions::ServerError, 'Server error', response)
59
66
  else
60
67
  raise_exception(Quaderno::Exceptions::InvalidSubdomainOrToken, 'Invalid subdomain or token', response)
61
68
  end
@@ -71,7 +78,7 @@ class Quaderno::Base < OpenStruct
71
78
 
72
79
  party_response = get("#{authentication[:url]}ping.json",
73
80
  basic_auth: authentication[:basic_auth],
74
- headers: version_header.merge(authentication[:headers])
81
+ headers: default_headers.merge(authentication[:headers])
75
82
  )
76
83
 
77
84
  check_exception_for(party_response, { subdomain_or_token: true })
@@ -96,7 +103,7 @@ class Quaderno::Base < OpenStruct
96
103
 
97
104
  party_response = get("#{authentication[:url]}me.json",
98
105
  basic_auth: authentication[:basic_auth],
99
- headers: version_header.merge(authentication[:headers])
106
+ headers: default_headers.merge(authentication[:headers])
100
107
  )
101
108
 
102
109
  check_exception_for(party_response, { subdomain_or_token: true })
@@ -135,7 +142,17 @@ class Quaderno::Base < OpenStruct
135
142
  @_document ||= document
136
143
  end
137
144
 
145
+ def self.default_headers
146
+ user_agent_header.merge(version_header)
147
+ end
148
+
149
+ def self.user_agent_header
150
+ { "User-Agent" => ["Quaderno Ruby Gem #{Quaderno::VERSION}", @@user_agent_suffix].compact.join(' - ') }
151
+ end
152
+
138
153
  def self.version_header
139
154
  { 'Accept' => @@api_version.to_i.zero? ? "application/json" : "application/json; api_version=#{@@api_version.to_i}"}
140
155
  end
156
+
157
+ headers self.default_headers
141
158
  end
@@ -13,7 +13,7 @@ module Quaderno::Behavior
13
13
 
14
14
  response = put("#{authentication[:url]}#{api_model.api_path}/#{id}/block.json",
15
15
  basic_auth: authentication[:basic_auth],
16
- headers: version_header.merge(authentication[:headers])
16
+ headers: default_headers.merge(authentication[:headers])
17
17
  )
18
18
 
19
19
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -23,6 +23,17 @@ module Quaderno::Behavior
23
23
  element
24
24
  end
25
25
 
26
+ def all_from_url(url, options = {})
27
+ authentication = get_authentication(api_model: api_model)
28
+
29
+ response = get(url,
30
+ basic_auth: authentication[:basic_auth],
31
+ headers: default_headers.merge(authentication[:headers])
32
+ )
33
+
34
+ handle_all_response(response, authentication, options)
35
+ end
36
+
26
37
  def all(options = {})
27
38
  authentication = get_authentication(options.merge(api_model: api_model))
28
39
  filter = options.dup.delete_if { |k,v| %w(auth_token access_token api_url mode api_model).include? k.to_s }
@@ -30,28 +41,10 @@ module Quaderno::Behavior
30
41
  response = get("#{authentication[:url]}#{api_model.api_path}.json",
31
42
  query: filter,
32
43
  basic_auth: authentication[:basic_auth],
33
- headers: version_header.merge(authentication[:headers])
44
+ headers: default_headers.merge(authentication[:headers])
34
45
  )
35
46
 
36
- check_exception_for(response, { rate_limit: true, subdomain_or_token: true })
37
- array = response.parsed_response
38
- collection = Quaderno::Collection.new
39
-
40
- if is_a_document?
41
- array.each do |element|
42
- element[:authentication_data] = authentication
43
- api_model.parse_nested(element)
44
- collection << (new element)
45
- end
46
- else
47
- array.each { |element| collection << (new element) }
48
- end
49
-
50
- collection.rate_limit_info = response
51
- collection.current_page = response.headers['x-pages-currentpage']
52
- collection.total_pages = response.headers['x-pages-totalpages']
53
-
54
- collection
47
+ handle_all_response(response, authentication, options)
55
48
  end
56
49
 
57
50
  def find(id, options = {})
@@ -59,7 +52,7 @@ module Quaderno::Behavior
59
52
 
60
53
  response = get("#{authentication[:url]}#{api_model.api_path}/#{id}.json",
61
54
  basic_auth: authentication[:basic_auth],
62
- headers: version_header.merge(authentication[:headers])
55
+ headers: default_headers.merge(authentication[:headers])
63
56
  )
64
57
 
65
58
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -81,7 +74,7 @@ module Quaderno::Behavior
81
74
  response = post("#{authentication[:url]}#{api_model.api_path}.json",
82
75
  body: params.to_json,
83
76
  basic_auth: authentication[:basic_auth],
84
- headers: version_header.merge(authentication[:headers]).merge('Content-Type' => 'application/json')
77
+ headers: default_headers.merge(authentication[:headers]).merge('Content-Type' => 'application/json')
85
78
  )
86
79
 
87
80
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, required_fields: true })
@@ -103,7 +96,7 @@ module Quaderno::Behavior
103
96
  response = put("#{authentication[:url]}#{api_model.api_path}/#{id}.json",
104
97
  body: params.to_json,
105
98
  basic_auth: authentication[:basic_auth],
106
- headers: version_header.merge(authentication[:headers]).merge('Content-Type' => 'application/json')
99
+ headers: default_headers.merge(authentication[:headers]).merge('Content-Type' => 'application/json')
107
100
  )
108
101
 
109
102
  check_exception_for(response, { rate_limit: true, required_fields: true, subdomain_or_token: true, id: true })
@@ -123,7 +116,7 @@ module Quaderno::Behavior
123
116
 
124
117
  response = HTTParty.delete("#{authentication[:url]}#{ api_model.api_path }/#{ id }.json",
125
118
  basic_auth: authentication[:basic_auth],
126
- headers: version_header.merge(authentication[:headers])
119
+ headers: default_headers.merge(authentication[:headers])
127
120
  )
128
121
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true, has_documents: true })
129
122
 
@@ -134,6 +127,32 @@ module Quaderno::Behavior
134
127
 
135
128
  object
136
129
  end
130
+
131
+ private
132
+
133
+ def handle_all_response(response, authentication, request_options)
134
+ check_exception_for(response, { rate_limit: true, subdomain_or_token: true })
135
+ array = response.parsed_response
136
+ collection = Quaderno::Collection.new
137
+
138
+ if is_a_document?
139
+ array.each do |element|
140
+ element[:authentication_data] = authentication
141
+ api_model.parse_nested(element)
142
+ collection << (new element)
143
+ end
144
+ else
145
+ array.each { |element| collection << (new element) }
146
+ end
147
+
148
+ collection.rate_limit_info = response
149
+ collection.request_options = request_options
150
+ collection.collection_type = self
151
+ collection.has_more = response.headers['x-pages-hasmore']
152
+ collection.next_page_url = response.headers['x-pages-nextpage']
153
+
154
+ collection
155
+ end
137
156
  end
138
157
  end
139
158
  end
@@ -13,7 +13,7 @@ module Quaderno::Behavior
13
13
 
14
14
  party_response = api_model.get("#{authentication_data[:url]}#{api_model.api_path}/#{id}/deliver.json",
15
15
  basic_auth: authentication_data[:basic_auth],
16
- headers: self.class.version_header.merge(authentication_data[:headers])
16
+ headers: self.class.default_headers.merge(authentication_data[:headers])
17
17
  )
18
18
 
19
19
  api_model.check_exception_for(party_response, { rate_limit: true, subdomain_or_token: true, id: true, required_fields: true })
@@ -17,7 +17,7 @@ module Quaderno::Behavior
17
17
  response = api_model.post("#{authentication_data[:url]}#{api_model.api_path}/#{id}/payments.json",
18
18
  body: params,
19
19
  basic_auth: authentication_data[:basic_auth],
20
- headers: self.class.version_header.merge(authentication_data[:headers])
20
+ headers: self.class.default_headers.merge(authentication_data[:headers])
21
21
  )
22
22
 
23
23
  api_model.check_exception_for(response, { rate_limit: true, subdomain_or_token: true, required_fields: true })
@@ -35,7 +35,7 @@ module Quaderno::Behavior
35
35
 
36
36
  response = HTTParty.delete("#{authentication_data[:url]}#{api_model.api_path}/#{id}/payments/#{payment_id}.json",
37
37
  basic_auth: authentication_data[:basic_auth],
38
- headers: self.class.version_header.merge(authentication_data[:headers])
38
+ headers: self.class.default_headers.merge(authentication_data[:headers])
39
39
  )
40
40
 
41
41
  api_model.check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -13,7 +13,7 @@ module Quaderno::Behavior
13
13
 
14
14
  response = get("#{authentication[:url]}#{gateway}/#{@_retrieve_path}/#{gateway_id}.json",
15
15
  basic_auth: authentication[:basic_auth],
16
- headers: version_header.merge(authentication[:headers])
16
+ headers: default_headers.merge(authentication[:headers])
17
17
  )
18
18
 
19
19
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -1,23 +1,28 @@
1
1
  class Quaderno::Collection < Array
2
2
  include Quaderno::Helpers::RateLimit
3
3
 
4
- def current_page=(page_number)
5
- @page = page_number
4
+ def request_options=(options)
5
+ @request_options = options
6
6
  end
7
7
 
8
- def current_page
9
- @page.to_i || 1
8
+ def collection_type=(collection_type)
9
+ @collection_type = collection_type
10
10
  end
11
11
 
12
- def total_pages=(total_pages)
13
- @total_pages = total_pages
12
+ def has_more=(has_more_response)
13
+ @has_more = has_more_response
14
14
  end
15
15
 
16
- def total_pages
17
- @total_pages.to_i || 1
16
+ def next_page_url=(next_page_url)
17
+ @next_page_url = next_page_url
18
18
  end
19
19
 
20
- def pagination_info
21
- { current_page: current_page, total_pages: total_pages }
20
+ def has_more?
21
+ @has_more == 'true'
22
22
  end
23
- end
23
+
24
+ def next_page
25
+ return Quaderno::Collection.new unless has_more?
26
+ @collection_type.all_from_url(@next_page_url, @request_options)
27
+ end
28
+ end
@@ -24,6 +24,9 @@ module Quaderno::Exceptions
24
24
  class UnsupportedApiVersion < BaseException
25
25
  end
26
26
 
27
+ class ServerError < BaseException
28
+ end
29
+
27
30
  def self.included(receiver)
28
31
  receiver.send :extend, ClassMethods
29
32
  end
@@ -50,6 +53,8 @@ module Quaderno::Exceptions
50
53
  if params[:has_documents].nil? == false
51
54
  raise_exception(Quaderno::Exceptions::HasAssociatedDocuments, party_response.body, party_response) if party_response.response.class == Net::HTTPClientError
52
55
  end
56
+
57
+ raise_exception(Quaderno::Exceptions::ServerError, 'Server error', party_response) if party_response.response.is_a?(Net::HTTPServerError)
53
58
  end
54
59
 
55
60
  def raise_exception(klass, message, response)
@@ -13,7 +13,7 @@ class Quaderno::Report < Quaderno::Base
13
13
  response = get("#{authentication[:url]}#{api_model.api_path}/journal.json",
14
14
  query: filter,
15
15
  basic_auth: authentication[:basic_auth],
16
- headers: version_header.merge(authentication[:headers])
16
+ headers: default_headers.merge(authentication[:headers])
17
17
  )
18
18
 
19
19
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true })
@@ -28,7 +28,7 @@ class Quaderno::Report < Quaderno::Base
28
28
  response = get("#{authentication[:url]}#{api_model.api_path}/taxes.json",
29
29
  query: filter,
30
30
  basic_auth: authentication[:basic_auth],
31
- headers: version_header.merge(authentication[:headers])
31
+ headers: default_headers.merge(authentication[:headers])
32
32
  )
33
33
 
34
34
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true })
@@ -65,7 +65,7 @@ class Quaderno::Report < Quaderno::Base
65
65
  response = get("#{authentication[:url]}#{api_model.api_path}/#{tax_report_type}.json",
66
66
  query: filter,
67
67
  basic_auth: authentication[:basic_auth],
68
- headers: version_header.merge(authentication[:headers])
68
+ headers: default_headers.merge(authentication[:headers])
69
69
  )
70
70
 
71
71
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true })
@@ -75,4 +75,4 @@ class Quaderno::Report < Quaderno::Base
75
75
 
76
76
  collection
77
77
  end
78
- end
78
+ end
@@ -0,0 +1,4 @@
1
+ class Quaderno::ReportRequest < Quaderno::Base
2
+ api_model Quaderno::ReportRequest
3
+ api_path 'reporting/requests'
4
+ end
@@ -13,10 +13,10 @@ class Quaderno::Tax < Quaderno::Base
13
13
  authentication = get_authentication(options.merge(api_model: api_model))
14
14
  params = options.dup.delete_if { |k,v| %w(auth_token access_token api_url mode api_model).include? k.to_s }
15
15
 
16
- response = get("#{authentication[:url]}taxes/calculate.json",
16
+ response = get("#{authentication[:url]}tax_rates/calculate.json",
17
17
  query: params,
18
18
  basic_auth: authentication[:basic_auth],
19
- headers: version_header.merge(authentication[:headers])
19
+ headers: default_headers.merge(authentication[:headers])
20
20
  )
21
21
 
22
22
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -26,13 +26,13 @@ class Quaderno::Tax < Quaderno::Base
26
26
  data
27
27
  end
28
28
 
29
- def self.validate_vat_number(country, vat_number, options = {})
29
+ def self.validate_tax_id(country, tax_id, options = {})
30
30
  authentication = get_authentication(options.merge(api_model: api_model))
31
31
 
32
- response = get("#{authentication[:url]}taxes/validate.json",
33
- query: { country: country, vat_number: vat_number },
32
+ response = get("#{authentication[:url]}tax_ids/validate.json",
33
+ query: { country: country, tax_id: tax_id },
34
34
  basic_auth: authentication[:basic_auth],
35
- headers: version_header.merge(authentication[:headers])
35
+ headers: default_headers.merge(authentication[:headers])
36
36
  )
37
37
 
38
38
  check_exception_for(response, { rate_limit: true, subdomain_or_token: true, id: true })
@@ -42,6 +42,8 @@ class Quaderno::Tax < Quaderno::Base
42
42
 
43
43
  data
44
44
  end
45
+ # TODO: Temporary alias to be removed in future releases
46
+ self.singleton_class.send(:alias_method, :validate_vat_number, :validate_tax_id)
45
47
 
46
48
  def self.reports(options = {})
47
49
  authentication = get_authentication(options.merge(api_model: api_model))
@@ -50,7 +52,7 @@ class Quaderno::Tax < Quaderno::Base
50
52
  response = get("#{authentication[:url]}taxes/reports.json",
51
53
  query: params,
52
54
  basic_auth: authentication[:basic_auth],
53
- headers: version_header.merge(authentication[:headers])
55
+ headers: default_headers.merge(authentication[:headers])
54
56
  )
55
57
 
56
58
  array = response.parsed_response
@@ -1,3 +1,3 @@
1
1
  class Quaderno
2
- VERSION = "1.17.1"
2
+ VERSION = "2.1.2"
3
3
  end
data/lib/quaderno-ruby.rb CHANGED
@@ -3,10 +3,11 @@ end
3
3
 
4
4
  require 'ostruct'
5
5
 
6
+ require 'quaderno-ruby/version'
6
7
  require 'quaderno-ruby/helpers/rate_limit'
7
8
  require 'quaderno-ruby/exceptions/exceptions'
8
9
  require 'quaderno-ruby/helpers/authentication'
9
10
  require 'quaderno-ruby/collection'
10
11
 
11
12
  %w(block crud deliver payment retrieve).each { |filename| require "quaderno-ruby/behavior/#{filename}" }
12
- %w(base contact item invoice receipt credit income estimate expense recurring document_item report evidence payment webhook tax checkout_session).each { |filename| require "quaderno-ruby/#{ filename }" }
13
+ %w(base contact item invoice receipt credit income estimate expense recurring document_item report report_request evidence payment webhook tax checkout_session).each { |filename| require "quaderno-ruby/#{ filename }" }
data/quaderno.gemspec CHANGED
@@ -4,30 +4,29 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'quaderno-ruby/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "quaderno"
7
+ spec.name = 'quaderno'
8
8
  spec.version = Quaderno::VERSION
9
- spec.authors = ["Recrea"]
10
- spec.email = "carlos@recrea.es"
9
+ spec.authors = ['Recrea']
10
+ spec.email = 'carlos@recrea.es'
11
11
 
12
- spec.summary = "Ruby wrapper for the Quaderno API (https://quaderno.io/docs/api)"
13
- spec.description = " A ruby wrapper for Quaderno API "
14
- spec.homepage = "http://github.com/quaderno/quaderno-ruby"
15
- spec.licenses = ["MIT"]
12
+ spec.summary = 'Ruby wrapper for the Quaderno API (https://quaderno.io/docs/api)'
13
+ spec.description = ' A ruby wrapper for Quaderno API '
14
+ spec.homepage = 'http://github.com/quaderno/quaderno-ruby'
15
+ spec.licenses = ['MIT']
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
18
+ spec.bindir = 'exe'
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = %w(lib)
21
- spec.date = "2018-05-07"
21
+ spec.date = '2018-05-07'
22
22
  spec.extra_rdoc_files = %w(LICENSE.txt README.md)
23
23
 
24
-
25
- spec.add_dependency('httparty', "~> 0.13")
26
- spec.add_development_dependency('rdoc', "~> 3.12")
27
- spec.add_development_dependency('activesupport', "~> 4.2.0")
28
- spec.add_development_dependency('webmock', "~> 1.22.6")
29
- spec.add_development_dependency('vcr', ">= 0")
30
- spec.add_development_dependency("bundler", "~> 1.11")
31
- spec.add_development_dependency("rake", ">= 12.3.3")
32
- spec.add_development_dependency("rspec", "~> 3.0")
24
+ spec.add_dependency('httparty', '~> 0.13')
25
+ spec.add_development_dependency('rdoc', '>= 6.3.1')
26
+ spec.add_development_dependency('activesupport', '~> 4.2.0')
27
+ spec.add_development_dependency('webmock', '~> 1.22.6')
28
+ spec.add_development_dependency('vcr', '>= 0')
29
+ spec.add_development_dependency('bundler', '~> 2.2')
30
+ spec.add_development_dependency('rake', '>= 12.3.3')
31
+ spec.add_development_dependency('rspec', '~> 3.0')
33
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quaderno
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.17.1
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Recrea
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rdoc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '3.12'
33
+ version: 6.3.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '3.12'
40
+ version: 6.3.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '1.11'
89
+ version: '2.2'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '1.11'
96
+ version: '2.2'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -131,9 +131,9 @@ extra_rdoc_files:
131
131
  - README.md
132
132
  files:
133
133
  - ".document"
134
+ - ".github/workflows/test.yml"
134
135
  - ".gitignore"
135
136
  - ".rspec"
136
- - ".travis.yml"
137
137
  - Gemfile
138
138
  - LICENSE.txt
139
139
  - README.md
@@ -164,6 +164,7 @@ files:
164
164
  - lib/quaderno-ruby/receipt.rb
165
165
  - lib/quaderno-ruby/recurring.rb
166
166
  - lib/quaderno-ruby/report.rb
167
+ - lib/quaderno-ruby/report_request.rb
167
168
  - lib/quaderno-ruby/tax.rb
168
169
  - lib/quaderno-ruby/version.rb
169
170
  - lib/quaderno-ruby/webhook.rb
@@ -187,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
188
  - !ruby/object:Gem::Version
188
189
  version: '0'
189
190
  requirements: []
190
- rubygems_version: 3.0.8
191
+ rubygems_version: 3.1.6
191
192
  signing_key:
192
193
  specification_version: 4
193
194
  summary: Ruby wrapper for the Quaderno API (https://quaderno.io/docs/api)
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.1
4
- before_install: gem install bundler -v 1.11.2