orangedata 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +3 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +32 -34
- data/README.md +15 -11
- data/Rakefile +46 -0
- data/lib/orange_data/credentials.rb +31 -3
- data/lib/orange_data/generated_attributes.rb +4 -0
- data/lib/orange_data/receipt.rb +6 -1
- data/lib/orange_data/schema_definitions.yml +238 -174
- data/lib/orange_data/transport.rb +67 -10
- data/lib/orange_data/version.rb +1 -1
- data/tmp/.keep +0 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3b6d9355317d3e78b2221d312c41f88b239fb29
|
4
|
+
data.tar.gz: 9ae406eeec23d3445b59293bd932b883e554f60e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65ed68e2a634ec632e316f1ea4f180b7dbc19d2fb7770ddf7a541d48a6a6470a09855911162d0dd295f0ac0b3fe0efa50cee58cfbf4e796c96dd6dd9dddd77ea
|
7
|
+
data.tar.gz: 6816521a818a22ffadbea061198c0c0b79a7a07e06aff1cd2f86cea2f45fc3eba6a37f88cc15a4f5aa6c828eefaf01bb5a9a6595b202a3ff07e0052f80bca22d
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# 0.0.6
|
2
|
+
|
3
|
+
- data schema changes:
|
4
|
+
- title attribute used for field names instead of description
|
5
|
+
- printable field names in `print` attribute
|
6
|
+
|
7
|
+
- Added: `set_agent_info`
|
8
|
+
- Added: for development: `rake swagger:diff` to detect upstream schema changes
|
9
|
+
- Changed: methods now return a wrapped result
|
10
|
+
- Fixed: key loading now works on ruby 2.5+ (#1)
|
data/Gemfile.lock
CHANGED
@@ -1,70 +1,68 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
orangedata (0.0.
|
4
|
+
orangedata (0.0.6)
|
5
5
|
faraday (>= 0.15)
|
6
6
|
faraday_middleware
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
addressable (2.
|
11
|
+
addressable (2.6.0)
|
12
12
|
public_suffix (>= 2.0.2, < 4.0)
|
13
13
|
ast (2.4.0)
|
14
14
|
crack (0.4.3)
|
15
15
|
safe_yaml (~> 1.0.0)
|
16
16
|
diff-lcs (1.3)
|
17
|
-
docile (1.3.
|
18
|
-
faraday (0.15.
|
17
|
+
docile (1.3.2)
|
18
|
+
faraday (0.15.4)
|
19
19
|
multipart-post (>= 1.2, < 3)
|
20
|
-
faraday_middleware (0.
|
20
|
+
faraday_middleware (0.13.1)
|
21
21
|
faraday (>= 0.7.4, < 1.0)
|
22
|
-
hashdiff (0.
|
23
|
-
jaro_winkler (1.5.
|
24
|
-
json (2.
|
22
|
+
hashdiff (0.4.0)
|
23
|
+
jaro_winkler (1.5.3)
|
24
|
+
json (2.2.0)
|
25
25
|
json-schema (2.8.1)
|
26
26
|
addressable (>= 2.4)
|
27
|
-
multipart-post (2.
|
28
|
-
parallel (1.
|
29
|
-
parser (2.
|
27
|
+
multipart-post (2.1.1)
|
28
|
+
parallel (1.17.0)
|
29
|
+
parser (2.6.3.0)
|
30
30
|
ast (~> 2.4.0)
|
31
|
-
|
32
|
-
public_suffix (3.0.3)
|
31
|
+
public_suffix (3.1.0)
|
33
32
|
rainbow (3.0.0)
|
34
33
|
rake (10.5.0)
|
35
|
-
rspec (3.
|
36
|
-
rspec-core (~> 3.
|
37
|
-
rspec-expectations (~> 3.
|
38
|
-
rspec-mocks (~> 3.
|
39
|
-
rspec-core (3.
|
40
|
-
rspec-support (~> 3.
|
41
|
-
rspec-expectations (3.
|
34
|
+
rspec (3.8.0)
|
35
|
+
rspec-core (~> 3.8.0)
|
36
|
+
rspec-expectations (~> 3.8.0)
|
37
|
+
rspec-mocks (~> 3.8.0)
|
38
|
+
rspec-core (3.8.1)
|
39
|
+
rspec-support (~> 3.8.0)
|
40
|
+
rspec-expectations (3.8.4)
|
42
41
|
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
-
rspec-support (~> 3.
|
44
|
-
rspec-mocks (3.
|
42
|
+
rspec-support (~> 3.8.0)
|
43
|
+
rspec-mocks (3.8.1)
|
45
44
|
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
-
rspec-support (~> 3.
|
47
|
-
rspec-support (3.
|
48
|
-
rubocop (0.
|
45
|
+
rspec-support (~> 3.8.0)
|
46
|
+
rspec-support (3.8.2)
|
47
|
+
rubocop (0.71.0)
|
49
48
|
jaro_winkler (~> 1.5.1)
|
50
49
|
parallel (~> 1.10)
|
51
|
-
parser (>= 2.
|
52
|
-
powerpack (~> 0.1)
|
50
|
+
parser (>= 2.6)
|
53
51
|
rainbow (>= 2.2.2, < 4.0)
|
54
52
|
ruby-progressbar (~> 1.7)
|
55
|
-
unicode-display_width (
|
56
|
-
ruby-progressbar (1.
|
57
|
-
safe_yaml (1.0.
|
53
|
+
unicode-display_width (>= 1.4.0, < 1.7)
|
54
|
+
ruby-progressbar (1.10.1)
|
55
|
+
safe_yaml (1.0.5)
|
58
56
|
simplecov (0.16.1)
|
59
57
|
docile (~> 1.1)
|
60
58
|
json (>= 1.8, < 3)
|
61
59
|
simplecov-html (~> 0.10.0)
|
62
60
|
simplecov-html (0.10.2)
|
63
|
-
unicode-display_width (1.
|
64
|
-
webmock (3.
|
61
|
+
unicode-display_width (1.6.0)
|
62
|
+
webmock (3.6.0)
|
65
63
|
addressable (>= 2.3.6)
|
66
64
|
crack (>= 0.3.2)
|
67
|
-
hashdiff
|
65
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
68
66
|
|
69
67
|
PLATFORMS
|
70
68
|
ruby
|
@@ -80,4 +78,4 @@ DEPENDENCIES
|
|
80
78
|
webmock
|
81
79
|
|
82
80
|
BUNDLED WITH
|
83
|
-
1.
|
81
|
+
1.17.3
|
data/README.md
CHANGED
@@ -7,28 +7,26 @@
|
|
7
7
|
A ruby client for orangedata.ru service.
|
8
8
|
Target service is pretty local to RU, so parts of readme will be in russian.
|
9
9
|
|
10
|
-
|
10
|
+
Ruby-клиент для сервиса онлайн-касс OrangeData
|
11
11
|
|
12
12
|
Умеет:
|
13
13
|
- собственно транспорт с подписью запросов
|
14
14
|
- сгенерировать ключ сразу в нужном виде
|
15
15
|
- маппинг для данных генерируется на базе приведенного в человеческий вид официального json-schema-описания
|
16
16
|
|
17
|
+
В планах получше подружить с рельсами.
|
18
|
+
|
19
|
+
На всякий случай disclaimer: API еще не полностью устоялось и возможно будет обновляться по мере обкатки.
|
20
|
+
|
17
21
|
## Установка
|
18
22
|
|
19
|
-
Все
|
23
|
+
Все стандартно - `bundle add orangedata`, либо по-старике пишем в Gemfile:
|
20
24
|
|
21
25
|
```ruby
|
22
26
|
gem 'orangedata'
|
23
27
|
```
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
$ bundle
|
28
|
-
|
29
|
-
Либо руками:
|
30
|
-
|
31
|
-
$ gem install orangedata
|
29
|
+
и давим `bundle`. Совсем руками можно `gem install orangedata`
|
32
30
|
|
33
31
|
## Использование
|
34
32
|
|
@@ -37,6 +35,12 @@ gem 'orangedata'
|
|
37
35
|
|
38
36
|
### Пробитие чека
|
39
37
|
|
38
|
+
Описание полей смотреть в [официальной документации](https://github.com/orangedata-official/API), названия маппинга и некоторые коментарии есть [в схеме данных](lib/orange_data/schema_definitions.yml) (метасхема расширений [тут](spec/lib/extensions_metaschema.yml)).
|
39
|
+
|
40
|
+
Для `enum`-полей есть маппинг, например `content.positions[0].tax` принимает значения: `:vat_18`, `:vat_10`, `:vat_18_118`, `:vat_10_110`, `:vat_0`, `:vat_not_charged`.
|
41
|
+
|
42
|
+
Простейший чек в тестовом окружении:
|
43
|
+
|
40
44
|
```ruby
|
41
45
|
transport = OrangeData::Transport.new("https://apip.orangedata.ru:2443/api/v2/", OrangeData::Credentials.default_test)
|
42
46
|
receipt = OrangeData::Receipt.income(inn:"1234567890"){|r|
|
@@ -82,9 +86,9 @@ gem 'orangedata'
|
|
82
86
|
```
|
83
87
|
|
84
88
|
### Чек коррекции
|
85
|
-
|
89
|
+
Осторожно: в API не все значения поля `tax` соответствуют цифрам в `taxNSum`, поддержка OD ответила, что все ок, так и должно быть. Скорее всего непонятки с номерами налогов приехали еще из налоговой, т.к. номера тегов тут идут подряд.
|
86
90
|
|
87
|
-
|
91
|
+
Поэтому в маппинге есть алиасы:
|
88
92
|
|
89
93
|
```ruby
|
90
94
|
transport = OrangeData::Transport.new("https://apip.orangedata.ru:2443/api/v2/", OrangeData::Credentials.default_test)
|
data/Rakefile
CHANGED
@@ -6,3 +6,49 @@ require 'rspec/core/rake_task'
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
8
|
task default: :spec
|
9
|
+
|
10
|
+
|
11
|
+
namespace :swagger do
|
12
|
+
swagger_file_name = 'tmp/swagger.json'
|
13
|
+
|
14
|
+
task :environment do
|
15
|
+
require 'json'
|
16
|
+
require 'orangedata'
|
17
|
+
end
|
18
|
+
|
19
|
+
file swagger_file_name => :environment do
|
20
|
+
puts "Downloading swagger.json"
|
21
|
+
`curl https://apip.orangedata.ru:2443/swagger/v2/swagger.json > #{swagger_file_name}`
|
22
|
+
end
|
23
|
+
|
24
|
+
task diff: [:environment, swagger_file_name] do
|
25
|
+
swagger = JSON.parse(File.read(swagger_file_name))
|
26
|
+
|
27
|
+
new_definitions = swagger['definitions']
|
28
|
+
old_definitions = OrangeData::PAYLOAD_SCHEMA['definitions']
|
29
|
+
|
30
|
+
if new_definitions.keys != old_definitions.keys
|
31
|
+
puts "New schema definitions: #{new_definitions.keys - old_definitions.keys}"
|
32
|
+
puts "Removed schema definitions: #{old_definitions.keys - new_definitions.keys}"
|
33
|
+
else
|
34
|
+
puts "No top-level definitions changed"
|
35
|
+
end
|
36
|
+
|
37
|
+
new_definitions.each_pair do|key, new_schema|
|
38
|
+
old_schema = old_definitions[key]
|
39
|
+
next unless old_schema
|
40
|
+
|
41
|
+
if old_schema['properties'].keys != new_schema['properties'].keys
|
42
|
+
if old_schema['properties'].keys.sort != new_schema['properties'].keys.sort
|
43
|
+
puts "\t#{key} added: #{new_schema['properties'].keys - old_schema['properties'].keys}"
|
44
|
+
puts "\t#{key} removed: #{old_schema['properties'].keys - new_schema['properties'].keys}"
|
45
|
+
else
|
46
|
+
puts "\t#{key} property order changed"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
#TODO: deep compare
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -44,9 +44,37 @@ module OrangeData
|
|
44
44
|
|
45
45
|
def from_hash(hash)
|
46
46
|
OpenSSL::PKey::RSA.new.tap do |key|
|
47
|
-
key.
|
48
|
-
|
49
|
-
|
47
|
+
if key.respond_to?(:set_key)
|
48
|
+
# ruby 2.5+
|
49
|
+
# a bit ugly - simulating with_indifferent_access
|
50
|
+
if hash['n'] || hash[:n]
|
51
|
+
# public key only has n and e (without them - there's no key actually)
|
52
|
+
key.set_key(
|
53
|
+
OpenSSL::BN.new(Base64.decode64(hash['n'] || hash[:n]), 2),
|
54
|
+
OpenSSL::BN.new(Base64.decode64(hash['e'] || hash[:e]), 2),
|
55
|
+
(hash['d'] || hash[:d]) && OpenSSL::BN.new(Base64.decode64(hash['d'] || hash[:d]), 2)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
if hash['p'] || hash[:p]
|
60
|
+
key.set_factors(
|
61
|
+
OpenSSL::BN.new(Base64.decode64(hash['p'] || hash[:p]), 2),
|
62
|
+
OpenSSL::BN.new(Base64.decode64(hash['q'] || hash[:q]), 2)
|
63
|
+
)
|
64
|
+
if hash['dmp1'] || hash[:dmp1]
|
65
|
+
key.set_crt_params(
|
66
|
+
OpenSSL::BN.new(Base64.decode64(hash['dmp1'] || hash[:dmp1]), 2),
|
67
|
+
OpenSSL::BN.new(Base64.decode64(hash['dmq1'] || hash[:dmq1]), 2),
|
68
|
+
OpenSSL::BN.new(Base64.decode64(hash['iqmp'] || hash[:iqmp]), 2)
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
else
|
73
|
+
# ruby 2.3 and may be older
|
74
|
+
key.params.keys.each do |param|
|
75
|
+
if (v = hash[param] || hash[param.to_sym])
|
76
|
+
key.send(:"#{param}=", OpenSSL::BN.new(Base64.decode64(v), 2))
|
77
|
+
end
|
50
78
|
end
|
51
79
|
end
|
52
80
|
end
|
@@ -110,6 +110,10 @@ module OrangeData
|
|
110
110
|
self
|
111
111
|
end
|
112
112
|
|
113
|
+
def attributes
|
114
|
+
to_hash.map{|(k,v)| [k.underscore, v] }.to_h
|
115
|
+
end
|
116
|
+
|
113
117
|
def ==(other)
|
114
118
|
self.class == other.class && to_hash == other.to_hash
|
115
119
|
# @payload == other.instance_variable_get(:@payload)
|
data/lib/orange_data/receipt.rb
CHANGED
@@ -95,7 +95,11 @@ module OrangeData
|
|
95
95
|
@additional_user_attribute = AdditionalUserAttribute.new.assign_attributes(options)
|
96
96
|
end
|
97
97
|
|
98
|
-
|
98
|
+
def set_agent_info(**options)
|
99
|
+
# agent info may have some validations/transformations, so
|
100
|
+
agent_info = AgentInfo.new.assign_attributes(options)
|
101
|
+
assign_attributes(agent_info.attributes.reject{|_k,v| v.nil?})
|
102
|
+
end
|
99
103
|
|
100
104
|
class Position < PayloadContent
|
101
105
|
def initialize(payload={})
|
@@ -182,6 +186,7 @@ module OrangeData
|
|
182
186
|
|
183
187
|
def qr_code_content
|
184
188
|
# Пример: t=20150720T1638&s=9999999.00&fn=000110000105&i=12345678&fp=123456&n=2
|
189
|
+
# вообще это тег 1196, но OD его не присылают
|
185
190
|
{
|
186
191
|
# - t=<date/time - дата и время осуществления расчета в формате ГГГГММДДТЧЧММ>
|
187
192
|
t: processed_at.gsub(/:\d{2}\z/, '').gsub(/[^0-9T]/, ''),
|