sale 0.2.1 → 0.4.0

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: 4d3a677bb61cfa0802ba091302eac81313419d154288c92d7fc4777f6d8eac45
4
- data.tar.gz: e480347c0acd0c4c614117bb2cd9735d9a1cd67834d184fc45c222ef8dc3f30a
3
+ metadata.gz: 47f45ce3b44b7b5fbb12004cd48c036ed4311b1636d066e710cf893b9054501f
4
+ data.tar.gz: 706f16546a82e63010784563e5b5d071ae670a7a451af813fd7b7fdeea3a96d7
5
5
  SHA512:
6
- metadata.gz: c1db560494d74856dc9190d8dc058cd6c6e72c24d4866123cba083a00685fb53ab572a84c5ef1dda52867ca4a48da2c0c85ff1f88a18ecb9b396e7fc9a8f85f0
7
- data.tar.gz: 0ba64f08387d786591f456388b9ca02089c2bb07d3b89fff2e12fc5f5fd4902d5ddba80554460b568939df35e433917202ded87bfd7b69151dd1b5b5775d23aa
6
+ metadata.gz: bc691f52018bd5cc2981b9738331d2c58278209e69d51107e06283e1d21b8b476d8da3cc17572fc08d2d15023dcfb2025a12bcbcb4629e9d78867a5eaed07f9e
7
+ data.tar.gz: cd1e8be8565f92513c86df4206670d3bc82dfde2d18cc571155afe19896a473885766f25a9416f8ad1768ec99ebb48130898eb212e4ea6fd7eff8350d43677dc
@@ -0,0 +1,2 @@
1
+ gems.locked
2
+ pkg
@@ -4,6 +4,8 @@ require_relative './entity'
4
4
 
5
5
  module Bsale
6
6
  class InvalidResponseError < StandardError; end
7
+ class ClientError < InvalidResponseError; end
8
+ class ServerError < InvalidResponseError; end
7
9
 
8
10
  class APIBase
9
11
  ENDPOINT = 'https://api.bsale.cl'.freeze
@@ -39,22 +41,27 @@ module Bsale
39
41
  headers = { 'access_token' => @token }
40
42
  url = path['://'] ? path : [ ENDPOINT, VERSION, path ].join('/')
41
43
 
42
- if @http
43
- @http.request(method, url, body, { json: true, follow: 3, headers: headers })
44
+ resp = if @http
45
+ @http.request(method, url, body, { json: true, follow: 3, retries: 3, headers: headers })
44
46
  else
45
- Dagger.request(method, url, body, { json: true, follow: 3, headers: headers })
47
+ Dagger.request(method, url, body, { json: true, follow: 3, retries: 3, headers: headers })
46
48
  end
47
- rescue InvalidResponseError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::EINVAL, Timeout::Error, \
48
- SocketError, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, OpenSSL::SSL::SSLError => e
49
49
 
50
+ if resp.code > 500
51
+ raise ServerError.new("#{resp.code}: #{resp.body}")
52
+ else
53
+ resp
54
+ end
55
+
56
+ rescue ServerError => e
50
57
  raise if attempt > MAX_RETRIES
51
- puts "Connection refused. Retrying in a few secs... (attempt #{attempt})"
52
- sleep(attempt * 5) # 5 secs, 10 secs, 15 secs, 20 secs
58
+ puts "#{e.class}. Retrying in a few secs... (attempt #{attempt})"
59
+ sleep(attempt * 3) # 3 secs, 6 secs, 9 secs, 12 secs
53
60
  request(method, path, body, attempt + 1)
54
61
  end
55
62
 
56
- def connect
57
- @http ||= Dagger.open(ENDPOINT)
63
+ def connect(opts = {})
64
+ @http ||= Dagger.open(ENDPOINT, opts)
58
65
  end
59
66
 
60
67
  def disconnect
@@ -68,8 +75,10 @@ module Bsale
68
75
  if resp.success?
69
76
  data = parse_json(resp.body)
70
77
  return data ? Entity.new(data, self, original_params) : nil
78
+ # elsif resp.code > 500
79
+ # raise ServerError.new("#{resp.code}: #{resp.body}")
71
80
  else
72
- raise InvalidResponseError.new("#{resp.code}: #{resp.body}")
81
+ raise ClientError.new("#{resp.code}: #{resp.body}")
73
82
  end
74
83
  end
75
84
 
@@ -1,3 +1,6 @@
1
+ require 'cgi'
2
+ require 'dagger'
3
+
1
4
  class Entity
2
5
  include Enumerable
3
6
 
@@ -40,6 +43,10 @@ class Entity
40
43
  to_a.size
41
44
  end
42
45
 
46
+ def total_entries
47
+ data['count']
48
+ end
49
+
43
50
  alias_method :size, :count
44
51
 
45
52
  def items
@@ -56,19 +63,19 @@ class Entity
56
63
  end
57
64
 
58
65
  def has_prev_page?
59
- data['prev']
66
+ !!data['prev']
60
67
  end
61
68
 
62
69
  def has_next_page?
63
- data['next']
70
+ !!data['next']
64
71
  end
65
72
 
66
73
  def prev_page
67
- data['prev'] ? follow_link(data['prev'], @original_params) : nil
74
+ data['prev'] ? follow_link(fix_link(data['prev']), @original_params) : nil
68
75
  end
69
76
 
70
77
  def next_page
71
- data['next'] ? follow_link(data['next'], @original_params) : nil
78
+ data['next'] ? follow_link(fix_link(data['next']), @original_params) : nil
72
79
  end
73
80
 
74
81
  def method_missing(name, *args)
@@ -97,13 +104,21 @@ class Entity
97
104
  # false
98
105
  # end
99
106
 
107
+ def fix_link(href)
108
+ uri = URI.parse(href)
109
+ link_params = CGI.parse(uri.query || '').transform_values(&:first)
110
+ new_params = maybe_stringify(@original_params || {}).merge(link_params)
111
+ uri.query = Dagger::Utils.encode(new_params) if new_params.any?
112
+ uri.to_s
113
+ end
114
+
100
115
  def is_hash?(obj)
101
116
  obj.is_a?(Hash)
102
117
  end
103
118
 
104
119
  def maybe_stringify(obj)
105
120
  return obj unless is_hash?(obj)
106
- obj.inject({}) { |memo,(k,v) | memo[k.to_s] = v; memo }
121
+ obj.inject({}) { |memo,(k,v)| memo[k.to_s] = v; memo }
107
122
  end
108
123
 
109
124
  def follow_link(href, params = nil)
@@ -17,16 +17,23 @@ class Bsale::Invoices
17
17
  end
18
18
  end
19
19
 
20
- def create(codeSii:, emissionDate:, expirationDate:, declareSii:, priceListId:, \
20
+ def create(codeSii: nil, documentTypeId: nil, emissionDate:, expirationDate:, declareSii:, priceListId:, \
21
21
  officeId: nil, clientId: nil, client: nil, details: nil, payments: nil)
22
22
 
23
23
  body = {
24
- codeSii: codeSii, # we could also use "documentTypeId"
25
24
  declareSii: declareSii,
26
25
  emissionDate: emissionDate,
27
26
  expirationDate: expirationDate
28
27
  }
29
28
 
29
+ if documentTypeId
30
+ body[:documentTypeId] = documentTypeId
31
+ elsif codeSii
32
+ body[:codeSii] = codeSii
33
+ else
34
+ raise ArgumentError, "Either codeSii or documentTypeId required"
35
+ end
36
+
30
37
  body[:officeId] = officeId if officeId
31
38
  body[:priceListId] = priceListId if priceListId
32
39
 
@@ -35,7 +42,7 @@ class Bsale::Invoices
35
42
  elsif client
36
43
  body[:client] = client
37
44
  elsif [33, 34].include?(codeSii.to_i) # facturas requiren clientId
38
- raise 'clientId or client required'
45
+ raise 'clientId or client required'
39
46
  end
40
47
 
41
48
  body[:details] = details if details
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'sale'
6
- s.version = '0.2.1'
6
+ s.version = '0.4.0'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ['Tomás Pollak']
9
9
  s.email = ['tomas@bootic.net']
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.add_development_dependency "rspec-mocks"
18
18
  s.add_development_dependency "rspec-expectations"
19
19
 
20
- s.add_runtime_dependency "dagger", "~> 0.9.0"
20
+ s.add_runtime_dependency "dagger", "~> 1.8.0"
21
21
 
22
22
  s.files = `git ls-files`.split("\n")
23
23
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
@@ -13,7 +13,7 @@ describe 'APIBase' do
13
13
  describe '#request' do
14
14
  it 'explodes with 401 error if invalid token' do
15
15
  expect do
16
- resp = subject.get('foo')
16
+ resp = subject.get('foo.json')
17
17
  end.to raise_error(Bsale::InvalidResponseError)
18
18
  end
19
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-24 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.9.0
75
+ version: 1.8.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.9.0
82
+ version: 1.8.0
83
83
  description: A wrapper around the Bsale API.
84
84
  email:
85
85
  - tomas@bootic.net
@@ -87,6 +87,7 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - ".gitignore"
90
91
  - Rakefile
91
92
  - gems.rb
92
93
  - lib/sale.rb