sale 0.0.5 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41b3070ba8aee6e1d58949a0405a9ccd0cd678c2
4
- data.tar.gz: cc8ac9ef4e99db45cdf989b86b17f44235f74028
3
+ metadata.gz: 312a98d959d5067f7a8fc7fbe56d1691ff5ba2d8
4
+ data.tar.gz: 4e053b4c611549eb2fa7481b2233923b62b7f460
5
5
  SHA512:
6
- metadata.gz: 70c0939f67ff45c566dab09e76e1a02f6e00f10f11febaa7bafe585e9964946a4632d9de2375f67989b584629954834e547b9ca2514d8300c98b04fc96d374ee
7
- data.tar.gz: 35b7b13e5f26abab3b907dc47244d3511300a2cb227d62a2245d318d1e219f11dc32bd5a78f006b6e2edd2a3568425f9a9721d934f04547bbf84791ca108d754
6
+ metadata.gz: a3562c9ab1d2e86adfc57078ee8e6b5e5df549431e84f815369440fd68f02a074b85b632f611bf02eae000d03e4873930f273819ea1eae8975657c97ef257408
7
+ data.tar.gz: '064964f9154ba0851097d2686341c783762c789cad6ae8eb2c1ec90fc14e3a60467206cf92499e7028f92931bd5e394514633330a254f7d47b6060ce47310a30'
data/lib/base.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'dagger'
2
2
  require 'json'
3
+ require_relative './entity'
3
4
 
4
5
  module Bsale
5
6
  class InvalidResponseError < StandardError; end
@@ -12,18 +13,47 @@ module Bsale
12
13
  @token = token or raise 'Token not set!'
13
14
  end
14
15
 
15
- private
16
+ def get(path, params = nil)
17
+ path = params.nil? ? path : path + "?" + Dagger::Utils.encode(params)
18
+ resp = request(:get, path)
19
+ wrap_response(resp, params)
20
+ end
21
+
22
+ def post(path, data)
23
+ resp = request(:post, path, data)
24
+ wrap_response(resp)
25
+ end
26
+
27
+ def put(path, data)
28
+ resp = request(:put, path, data)
29
+ wrap_response(resp)
30
+ end
16
31
 
17
32
  def request(method, path, body = nil)
18
33
  headers = { 'access_token' => @token }
19
34
  url = path['://'] ? path : [ ENDPOINT, VERSION, path ].join('/')
20
- Dagger.request(method, url, body, { json: true, follow: 3, headers: headers })
35
+
36
+ if @http
37
+ @http.request(method, url, body, { json: true, follow: 3, headers: headers })
38
+ else
39
+ Dagger.request(method, url, body, { json: true, follow: 3, headers: headers })
40
+ end
41
+ end
42
+
43
+ def connect
44
+ @http ||= Dagger.open(ENDPOINT)
21
45
  end
22
46
 
23
- def handle_response(resp)
47
+ def disconnect
48
+ @http.close if @http
49
+ end
50
+
51
+ private
52
+
53
+ def wrap_response(resp, original_params = nil)
24
54
  if resp.success?
25
55
  data = parse_json(resp.body)
26
- return data ? OpenStruct.new(data) : nil
56
+ return data ? Entity.new(data, self, original_params) : nil
27
57
  else
28
58
  raise InvalidResponseError.new("#{resp.code}: #{resp.body}")
29
59
  end
data/lib/bsale.rb CHANGED
@@ -1,2 +1,45 @@
1
1
  require_relative './buyers'
2
- require_relative './documents'
2
+ require_relative './invoices'
3
+
4
+ class Bsale::Root < Bsale::APIBase
5
+
6
+ PATHS = [
7
+ 'book_types',
8
+ 'coins',
9
+ 'clients',
10
+ 'discounts',
11
+ 'documents',
12
+ 'dte_codes',
13
+ 'document_types',
14
+ 'offices',
15
+ 'payments',
16
+ 'payment_types',
17
+ 'price_lists',
18
+ 'product_types',
19
+ 'products',
20
+ 'sale_conditions',
21
+ 'shipping_types',
22
+ 'shippings',
23
+ 'stocks',
24
+ 'returns',
25
+ 'taxes',
26
+ 'third_party_documents',
27
+ 'users',
28
+ 'variants'
29
+ ].freeze
30
+
31
+ def method_missing(name, params = nil)
32
+ if PATHS.include?(name.to_s)
33
+ get("#{name}.json", params)
34
+ end
35
+ end
36
+
37
+ def buyers
38
+ Buyers.new(self)
39
+ end
40
+
41
+ def invoices
42
+ Invoices.new(self)
43
+ end
44
+
45
+ end
data/lib/buyers.rb CHANGED
@@ -1,12 +1,17 @@
1
1
  require_relative './base'
2
2
 
3
- class Bsale::Buyers < Bsale::APIBase
3
+ class Bsale::Buyers
4
+
5
+ def initialize(root)
6
+ @client = client
7
+ end
8
+
4
9
  class BuyerNotFoundError < Bsale::InvalidResponseError; end
5
10
 
6
11
  EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
7
12
 
8
- def get_buyer_with_email_and_code(email, code = nil)
9
- if list = get_buyers_with_email(email) and list.any?
13
+ def find_by_email_and_code(email, code = nil)
14
+ if list = find_all_by_email(email) and list.any?
10
15
  with_code = list.select { |b| code.nil? ? (b.code || '').size > 0 : (code.to_s == b.code.to_s) }
11
16
 
12
17
  if with_code.count != 1
@@ -17,16 +22,16 @@ class Bsale::Buyers < Bsale::APIBase
17
22
  end
18
23
  end
19
24
 
20
- def get_buyers_with_email(email)
25
+ def find_all_by_email(email)
21
26
  return nil unless email && email.match(EMAIL_REGEX)
22
27
  get_buyers_with(email: email)
23
28
  end
24
29
 
25
- def get_buyers_with_code(code)
30
+ def find_all_by_email(code)
26
31
  get_buyers_with(code: code)
27
32
  end
28
33
 
29
- def add_buyer(firstName:, lastName:, address:, email:, phone:, code:, note:, activity:, municipality:, city:)
34
+ def create(firstName:, lastName:, address:, email:, phone:, code:, note:, activity:, municipality:, city:)
30
35
  data = {
31
36
  accumulatePoints: 1,
32
37
  firstName: firstName,
@@ -42,21 +47,19 @@ class Bsale::Buyers < Bsale::APIBase
42
47
  }
43
48
 
44
49
  return nil unless email.match(EMAIL_REGEX)
45
- resp = request(:post, "/clients.json", data)
46
- handle_response(resp)
50
+ client.post("/clients.json", data)
47
51
  end
48
52
 
49
- def update_buyer(id, data)
53
+ def update(id, data)
50
54
  if [:email, :code].include?(data.symbolize_keys.keys)
51
55
  raise 'Invalid request, cannot update email nor code!'
52
56
  end
53
57
 
54
58
  # puts "Updating client #{id} with data: #{data.inspect}"
55
- resp = request(:put, "/clients/#{id}.json", data.merge(id: id))
56
- handle_response(resp)
59
+ client.put("/clients/#{id}.json", data.merge(id: id))
57
60
  end
58
61
 
59
- def update_buyer_points(buyer, difference, order_code)
62
+ def update_points(buyer, difference, order_code)
60
63
  raise 'No point in modifying 0 points' if difference == 0
61
64
 
62
65
  data = {
@@ -67,7 +70,7 @@ class Bsale::Buyers < Bsale::APIBase
67
70
  orderId: order_code
68
71
  }
69
72
 
70
- resp = request(:put, "/clients/points.json", data)
73
+ resp = client.request(:put, "/clients/points.json", data)
71
74
  if resp.code == 200
72
75
  return parse_json(resp.body)['points']
73
76
  else
@@ -76,6 +79,7 @@ class Bsale::Buyers < Bsale::APIBase
76
79
  end
77
80
 
78
81
  private
82
+ attr_reader :client
79
83
 
80
84
  def get_buyers_with(attrs)
81
85
  if data = get_buyers(attrs.merge(state: 0)) and data['items']
@@ -86,9 +90,7 @@ class Bsale::Buyers < Bsale::APIBase
86
90
  end
87
91
 
88
92
  def get_buyers(query)
89
- search = query.map { |k,v| URI.encode(k.to_s) + '=' + URI.encode(v.to_s) }.join('&')
90
- resp = request(:get, '/clients.json?' + search)
91
- resp.code == 200 ? parse_json(resp.body) : nil
93
+ client.clients(query)
92
94
  end
93
95
 
94
96
  end
data/lib/entity.rb ADDED
@@ -0,0 +1,103 @@
1
+ class Entity
2
+
3
+ attr_reader :data
4
+
5
+ def initialize(data, client, original_params = nil)
6
+ @data, @client, @original_params = data, client, original_params
7
+ end
8
+
9
+ def to_s
10
+ @data.inspect
11
+ end
12
+
13
+ def to_a
14
+ data['items'] ? items : nil
15
+ end
16
+
17
+ def [](key)
18
+ data[key.to_s]
19
+ end
20
+
21
+ def []=(key, obj)
22
+ data[key.to_s] = obj
23
+ end
24
+
25
+ def each(&block)
26
+ to_a.each(&block)
27
+ end
28
+
29
+ def each_with_index(&block)
30
+ to_a.each_with_index &block
31
+ end
32
+
33
+ def load(params = nil)
34
+ client.get(data['href'], params)
35
+ end
36
+
37
+ def reload
38
+ # @data = client.request('get', data['href'])
39
+ load # just return a new instance
40
+ end
41
+
42
+ def items
43
+ return if data['items'].nil?
44
+ @items ||= data['items'].map { |obj| Entity.new(obj, client) }
45
+ end
46
+
47
+ def first
48
+ items ? items.first : nil
49
+ end
50
+
51
+ def last
52
+ items ? items.last : nil
53
+ end
54
+
55
+ def has_prev_page?
56
+ data['prev']
57
+ end
58
+
59
+ def has_next_page?
60
+ data['next']
61
+ end
62
+
63
+ def prev_page
64
+ data['prev'] ? follow_link(data['prev'], @original_params) : nil
65
+ end
66
+
67
+ def next_page
68
+ data['next'] ? follow_link(data['next'], @original_params) : nil
69
+ end
70
+
71
+ def method_missing(name)
72
+ name = name.to_s
73
+
74
+ if data[name]
75
+ # if is_link?(data[name])
76
+ # follow_link(data[name]['href'])
77
+ if is_hash?(data[name])
78
+ Entity.new(data[name], client)
79
+ else
80
+ data[name]
81
+ end
82
+ else
83
+ # puts data.inspect
84
+ # puts "Unknown method: #{name}"
85
+ end
86
+ end
87
+
88
+ private
89
+ attr_reader :client
90
+
91
+ def is_link?(obj)
92
+ is_hash?(obj) && obj['href'] && obj.keys == ['href']
93
+ end
94
+
95
+ def is_hash?(obj)
96
+ obj.is_a?(Hash)
97
+ end
98
+
99
+ def follow_link(href, params = nil)
100
+ client.get(href, params)
101
+ end
102
+
103
+ end
data/lib/invoices.rb ADDED
@@ -0,0 +1,62 @@
1
+ require_relative './base'
2
+
3
+ class Bsale::Invoices
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ # actions
10
+
11
+ def get_pdf(url)
12
+ resp = request(:get, url)
13
+ if resp.success?
14
+ StringIO.new(resp.body, 'rb')
15
+ else
16
+ nil
17
+ end
18
+ end
19
+
20
+ def create(codeSii:, emissionDate:, expirationDate:, declareSii:, priceListId:, \
21
+ officeId: nil, clientId: nil, client: nil, details: nil, payments: nil)
22
+
23
+ body = {
24
+ codeSii: codeSii, # we could also use "documentTypeId"
25
+ declareSii: declareSii,
26
+ emissionDate: emissionDate,
27
+ expirationDate: expirationDate
28
+ }
29
+
30
+ body[:officeId] = officeId if officeId
31
+ body[:priceListId] = priceListId if priceListId
32
+
33
+ # facturas require clientId, unlike boletas
34
+ if [33, 34].include?(codeSii.to_i)
35
+ if clientId
36
+ body[:clientId] = clientId
37
+ elsif client
38
+ body[:client] = client
39
+ else
40
+ raise 'clientId or client required'
41
+ end
42
+ end
43
+
44
+ body[:details] = details if details
45
+ body[:payments] = payments if payments
46
+
47
+ client.post("documents.json", body.to_json)
48
+ end
49
+
50
+ def mark_declared(id)
51
+ body = { id: id, informedSii: 1 }
52
+ client.request(:put, 'documents/set_sii_state.json', body)
53
+ end
54
+
55
+ def remove(id:, office_id:)
56
+ client.request(:delete, "documents/#{id}.json?officeid=#{office_id}")
57
+ end
58
+
59
+ private
60
+ attr_reader :client
61
+
62
+ end
data/sale.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "sale"
6
- s.version = '0.0.5'
6
+ s.version = '0.1.0'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ['Tomás Pollak']
9
9
  s.email = ['tomas@bootic.net']
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.0.5
4
+ version: 0.1.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: 2017-11-03 00:00:00.000000000 Z
11
+ date: 2018-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -92,7 +92,8 @@ files:
92
92
  - lib/base.rb
93
93
  - lib/bsale.rb
94
94
  - lib/buyers.rb
95
- - lib/documents.rb
95
+ - lib/entity.rb
96
+ - lib/invoices.rb
96
97
  - sale.gemspec
97
98
  - spec/buyers_spec.rb
98
99
  homepage: https://github.com/github/bsale-api-wrapper
@@ -114,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
115
  version: 1.3.6
115
116
  requirements: []
116
117
  rubyforge_project:
117
- rubygems_version: 2.5.1
118
+ rubygems_version: 2.6.13
118
119
  signing_key:
119
120
  specification_version: 4
120
121
  summary: A wrapper around the Bsale API.
data/lib/documents.rb DELETED
@@ -1,80 +0,0 @@
1
- require_relative './base'
2
-
3
- class Bsale::Documents < Bsale::APIBase
4
-
5
- def get_document_types
6
- resp = request(:get, 'document_types.json')
7
- handle_response(resp)
8
- end
9
-
10
- def get_payment_types
11
- resp = request(:get, 'payment_types.json')
12
- handle_response(resp)
13
- end
14
-
15
- def get_tax_types
16
- resp = request(:get, 'taxes.json')
17
- handle_response(resp)
18
- end
19
-
20
- def get_price_lists
21
- resp = request(:get, 'price_lists.json')
22
- handle_response(resp)
23
- end
24
-
25
- def get_documents(params = {})
26
- query = Dagger::Utils.encode(params)
27
- resp = request(:get, "documents.json?#{query}")
28
- handle_response(resp)
29
- end
30
-
31
- def get_pdf(url)
32
- resp = request(:get, url)
33
- if resp.success?
34
- StringIO.new(resp.body, 'rb')
35
- else
36
- nil
37
- end
38
- end
39
-
40
- def create_doc(codeSii:, emissionDate:, expirationDate:, declareSii:, priceListId:, \
41
- officeId: nil, clientId: nil, client: nil, details: nil, payments: nil)
42
-
43
- body = {
44
- codeSii: codeSii, # we could also use "documentTypeId"
45
- declareSii: declareSii,
46
- emissionDate: emissionDate,
47
- expirationDate: expirationDate
48
- }
49
-
50
- body[:officeId] = officeId if officeId
51
- body[:priceListId] = priceListId if priceListId
52
-
53
- # facturas require clientId, unlike boletas
54
- if [33, 34].include?(codeSii.to_i)
55
- if clientId
56
- body[:clientId] = clientId
57
- elsif client
58
- body[:client] = client
59
- else
60
- raise 'clientId or client required'
61
- end
62
- end
63
-
64
- body[:details] = details if details
65
- body[:payments] = payments if payments
66
-
67
- resp = request(:post, "documents.json", body.to_json)
68
- handle_response(resp)
69
- end
70
-
71
- def mark_document_declared(id)
72
- body = { id: id, informedSii: 1 }
73
- request(:put, 'documents/set_sii_state.json', body)
74
- end
75
-
76
- def remove_document(id:, office_id:)
77
- request(:delete, "documents/#{id}.json?officeid=#{office_id}")
78
- end
79
-
80
- end