sale 0.0.5 → 0.1.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
  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