sale 0.0.1
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 +7 -0
- data/Rakefile +2 -0
- data/gems.rb +4 -0
- data/lib/base.rb +41 -0
- data/lib/bsale.rb +2 -0
- data/lib/buyers.rb +94 -0
- data/lib/documents.rb +74 -0
- data/sale.gemspec +26 -0
- data/spec/buyers_spec.rb +176 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5709e56615138240b522d2e4e92a8e68db8809aa
|
4
|
+
data.tar.gz: 3c4b2e2158939f9787e8d5685c158661c4f60635
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d3dcdea744947207aa95a4681debe802c85295c5c93974475389e7cf2c8771584f2fce31de24bb2ccdaa61e0c72b2e2efff604c14c3a49c7833858faf3a96e49
|
7
|
+
data.tar.gz: a8e887b2fe4b1dc16a04244f247e57da772bcf302ca0d6c36cad8628bef4897548d785cd4913ac7cc9277473d67af569ece0c0291c2430881951dc05471eaccd
|
data/Rakefile
ADDED
data/gems.rb
ADDED
data/lib/base.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'dagger'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Bsale
|
5
|
+
class InvalidResponseError < StandardError; end
|
6
|
+
|
7
|
+
class APIBase
|
8
|
+
ENDPOINT = 'https://api.bsale.cl'.freeze
|
9
|
+
VERSION = 'v1'.freeze
|
10
|
+
|
11
|
+
def initialize(token)
|
12
|
+
@token = token or raise 'Token not set!'
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def request(method, path, body = nil)
|
18
|
+
headers = { access_token: @token }
|
19
|
+
url = path['://'] ? path : [ ENDPOINT, VERSION, path ].join('/')
|
20
|
+
Dagger.request(method, url, body, { json: true, follow: 3, headers: headers })
|
21
|
+
end
|
22
|
+
|
23
|
+
def handle_response(resp)
|
24
|
+
if resp.success?
|
25
|
+
data = parse_json(resp.body)
|
26
|
+
return data ? OpenStruct.new(data) : nil
|
27
|
+
else
|
28
|
+
raise InvalidResponseError.new("#{resp.code}: #{resp.body}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_json(str)
|
33
|
+
JSON.parse(str)
|
34
|
+
rescue JSON::ParserError => e
|
35
|
+
puts "Invalid JSON: #{e.message}"
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/bsale.rb
ADDED
data/lib/buyers.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
class Bsale::Buyers < Bsale::APIBase
|
4
|
+
class BuyerNotFoundError < Bsale::InvalidResponseError; end
|
5
|
+
|
6
|
+
EMAIL_REGEX = /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
|
7
|
+
|
8
|
+
def get_buyer_with_email_and_code(email, code = nil)
|
9
|
+
if list = get_buyers_with_email(email) and list.any?
|
10
|
+
with_code = list.select { |b| code.nil? ? (b.code || '').size > 0 : (code.to_s == b.code.to_s) }
|
11
|
+
|
12
|
+
if with_code.count != 1
|
13
|
+
raise BuyerNotFoundError.new("#{with_code.count} clients under #{email} and code #{code}")
|
14
|
+
end
|
15
|
+
|
16
|
+
return with_code.first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_buyers_with_email(email)
|
21
|
+
return nil unless email && email.match(EMAIL_REGEX)
|
22
|
+
get_buyers_with(email: email)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_buyers_with_code(code)
|
26
|
+
get_buyers_with(code: code)
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_buyer(firstName:, lastName:, address:, email:, phone:, code:, note:, activity:, municipality:, city:)
|
30
|
+
data = {
|
31
|
+
accumulatePoints: 1,
|
32
|
+
firstName: firstName,
|
33
|
+
lastName: lastName,
|
34
|
+
code: code,
|
35
|
+
address: address,
|
36
|
+
email: email,
|
37
|
+
phone: phone,
|
38
|
+
city: city,
|
39
|
+
municipality: municipality,
|
40
|
+
note: note, # gender
|
41
|
+
activity: activity # date of birth
|
42
|
+
}
|
43
|
+
|
44
|
+
return nil unless email.match(EMAIL_REGEX)
|
45
|
+
resp = request(:post, "/clients.json", data)
|
46
|
+
handle_response(resp)
|
47
|
+
end
|
48
|
+
|
49
|
+
def update_buyer(id, data)
|
50
|
+
if [:email, :code].include?(data.symbolize_keys.keys)
|
51
|
+
raise 'Invalid request, cannot update email nor code!'
|
52
|
+
end
|
53
|
+
|
54
|
+
# puts "Updating client #{id} with data: #{data.inspect}"
|
55
|
+
resp = request(:put, "/clients/#{id}.json", data.merge(id: id))
|
56
|
+
handle_response(resp)
|
57
|
+
end
|
58
|
+
|
59
|
+
def update_buyer_points(buyer, difference, order_code)
|
60
|
+
raise 'No point in modifying 0 points' if difference == 0
|
61
|
+
|
62
|
+
data = {
|
63
|
+
email: buyer.email,
|
64
|
+
points: difference.abs,
|
65
|
+
type: difference > 0 ? 0 : 1, # 0 to add, 1 to subtract
|
66
|
+
description: "Apply #{difference} points from order #{order_code}",
|
67
|
+
orderId: order_code
|
68
|
+
}
|
69
|
+
|
70
|
+
resp = request(:put, "/clients/points.json", data)
|
71
|
+
if resp.code == 200
|
72
|
+
return parse_json(resp.body)['points']
|
73
|
+
else
|
74
|
+
raise InvalidResponseError.new("#{resp.code}: #{resp.body}")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def get_buyers_with(attrs)
|
81
|
+
if data = get_buyers(attrs.merge(state: 0)) and data['items']
|
82
|
+
data['items'].map { |item| OpenStruct.new(item) }
|
83
|
+
else
|
84
|
+
[]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
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
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
data/lib/documents.rb
ADDED
@@ -0,0 +1,74 @@
|
|
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_pdf(url)
|
26
|
+
resp = request(:get, url)
|
27
|
+
if resp.success?
|
28
|
+
StringIO.new(resp.body, 'rb')
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_doc(codeSii:, emissionDate:, expirationDate:, declareSii:, priceListId:, \
|
35
|
+
officeId: nil, clientId: nil, client: nil, details: nil, payments: nil)
|
36
|
+
|
37
|
+
body = {
|
38
|
+
codeSii: codeSii, # we could also use "documentTypeId"
|
39
|
+
declareSii: declareSii,
|
40
|
+
emissionDate: emissionDate,
|
41
|
+
expirationDate: expirationDate
|
42
|
+
}
|
43
|
+
|
44
|
+
body[:officeId] = officeId if officeId
|
45
|
+
body[:priceListId] = priceListId if priceListId
|
46
|
+
|
47
|
+
# facturas require clientId, unlike boletas
|
48
|
+
if [33, 34].include?(codeSii.to_i)
|
49
|
+
if clientId
|
50
|
+
body[:clientId] = clientId
|
51
|
+
elsif client
|
52
|
+
body[:client] = client
|
53
|
+
else
|
54
|
+
raise 'clientId or client required'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
body[:details] = details if details
|
59
|
+
body[:payments] = payments if payments
|
60
|
+
|
61
|
+
resp = request(:post, "documents.json", body.to_json)
|
62
|
+
handle_response(resp)
|
63
|
+
end
|
64
|
+
|
65
|
+
def mark_document_declared(id)
|
66
|
+
body = { id: id, informedSii: 1 }
|
67
|
+
request(:put, 'documents/set_sii_state.json', body)
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_document(id:, office_id:)
|
71
|
+
request(:delete, "documents/#{id}.json?officeid=#{office_id}")
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/sale.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# require File.expand_path("../lib/bsale/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "sale"
|
6
|
+
s.version = '0.0.1'
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Tomás Pollak']
|
9
|
+
s.email = ['tomas@bootic.net']
|
10
|
+
s.homepage = "https://github.com/github/bsale-api-wrapper"
|
11
|
+
s.summary = "A wrapper around the Bsale API."
|
12
|
+
s.description = "A wrapper around the Bsale API."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
16
|
+
s.add_development_dependency "rspec-core"
|
17
|
+
s.add_development_dependency "rspec-mocks"
|
18
|
+
s.add_development_dependency "rspec-expectations"
|
19
|
+
|
20
|
+
s.add_runtime_dependency "dagger", "~> 0.9.0"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
24
|
+
s.require_path = 'lib'
|
25
|
+
# s.bindir = 'bin'
|
26
|
+
end
|
data/spec/buyers_spec.rb
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require_relative '../lib/bsale'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
config.color = true
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'Bsale' do
|
9
|
+
|
10
|
+
describe 'Buyers' do
|
11
|
+
|
12
|
+
let(:client) {
|
13
|
+
Bsale::Buyers.new('foo')
|
14
|
+
}
|
15
|
+
|
16
|
+
let(:fake_response) {
|
17
|
+
double('Response', code: 200, body: '{"count": 0}')
|
18
|
+
}
|
19
|
+
|
20
|
+
before do
|
21
|
+
allow(Dagger).to receive(:request).and_return(fake_response)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'get_buyer_with_email_and_code' do
|
25
|
+
|
26
|
+
describe 'when email is invalid' do
|
27
|
+
|
28
|
+
it 'returns nil, without making a request' do
|
29
|
+
expect(client).not_to receive(:request)
|
30
|
+
client.get_buyer_with_email_and_code('aaa')
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'no results' do
|
36
|
+
|
37
|
+
before do
|
38
|
+
expect(fake_response).to receive(:body).and_return({ items: [] }.to_json)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns nil without code' do
|
42
|
+
client.get_buyer_with_email_and_code('aaa@foo.com')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns nil with code' do
|
46
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'one result with code' do
|
52
|
+
|
53
|
+
before do
|
54
|
+
expect(fake_response).to receive(:body).and_return({ items: [{ code: 123, accumulatePoints: '1' }] }.to_json)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns result, without code' do
|
58
|
+
res = client.get_buyer_with_email_and_code('aaa@foo.com')
|
59
|
+
expect(res).to eql(OpenStruct.new({ code: 123, accumulatePoints: '1' }))
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns result, with matching code' do
|
63
|
+
res = client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
64
|
+
expect(res).to eql(OpenStruct.new({ code: 123, accumulatePoints: '1' }))
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns nil, with non-matching code' do
|
68
|
+
expect do
|
69
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '234')
|
70
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe 'one result with code, another one without' do
|
76
|
+
|
77
|
+
before do
|
78
|
+
list = [{ code: 123, accumulatePoints: '1' }, { code: '', accumulatePoints: '1' }]
|
79
|
+
expect(fake_response).to receive(:body).and_return({ items: list }.to_json)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'returns result, without code' do
|
83
|
+
res = client.get_buyer_with_email_and_code('aaa@foo.com')
|
84
|
+
expect(res).to eql(OpenStruct.new({ code: 123, accumulatePoints: '1' }))
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns result, with matching code' do
|
88
|
+
res = client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
89
|
+
expect(res).to eql(OpenStruct.new({ code: 123, accumulatePoints: '1' }))
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'returns nil, with non-matching code' do
|
93
|
+
expect do
|
94
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '234')
|
95
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'two results with same code' do
|
101
|
+
|
102
|
+
before do
|
103
|
+
expect(fake_response).to receive(:body).and_return({ items: [{ code: 123 }, { code: 123 }] }.to_json)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns nil, without code' do
|
107
|
+
expect do
|
108
|
+
client.get_buyer_with_email_and_code('aaa@foo.com')
|
109
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'returns nil, with matching code' do
|
113
|
+
expect do
|
114
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
115
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'returns nil, with non-matching code' do
|
119
|
+
expect do
|
120
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '234')
|
121
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'two results with different codes' do
|
127
|
+
|
128
|
+
before do
|
129
|
+
list = [{ code: 123, accumulatePoints: '1' }, { code: 345, accumulatePoints: '1' }]
|
130
|
+
expect(fake_response).to receive(:body).and_return({ items: list }.to_json)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'returns nil, without code' do
|
134
|
+
expect do
|
135
|
+
client.get_buyer_with_email_and_code('aaa@foo.com')
|
136
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'returns result, when code matches one' do
|
140
|
+
res = client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
141
|
+
expect(res).to eql(OpenStruct.new({ code: 123, accumulatePoints: '1' }))
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'returns nil, when code doesnt match any' do
|
145
|
+
expect do
|
146
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '234')
|
147
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'two results without code' do
|
153
|
+
|
154
|
+
before do
|
155
|
+
expect(fake_response).to receive(:body).and_return({ items: [{ code: '' }, { code: '' }] }.to_json)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'returns nil, without code' do
|
159
|
+
expect do
|
160
|
+
client.get_buyer_with_email_and_code('aaa@foo.com')
|
161
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'returns nil, with code' do
|
165
|
+
expect do
|
166
|
+
client.get_buyer_with_email_and_code('aaa@foo.com', '123')
|
167
|
+
end.to raise_error(Bsale::Buyers::BuyerNotFoundError)
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sale
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tomás Pollak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-mocks
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-expectations
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dagger
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.9.0
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.9.0
|
83
|
+
description: A wrapper around the Bsale API.
|
84
|
+
email:
|
85
|
+
- tomas@bootic.net
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- Rakefile
|
91
|
+
- gems.rb
|
92
|
+
- lib/base.rb
|
93
|
+
- lib/bsale.rb
|
94
|
+
- lib/buyers.rb
|
95
|
+
- lib/documents.rb
|
96
|
+
- sale.gemspec
|
97
|
+
- spec/buyers_spec.rb
|
98
|
+
homepage: https://github.com/github/bsale-api-wrapper
|
99
|
+
licenses: []
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 1.3.6
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.5.1
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: A wrapper around the Bsale API.
|
121
|
+
test_files: []
|