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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f4b1c0d05572781e1ae1550991a896a7d81b9f2
4
- data.tar.gz: c3773260bb588960809e57153343ff187bdd90f1
3
+ metadata.gz: f3b6d9355317d3e78b2221d312c41f88b239fb29
4
+ data.tar.gz: 9ae406eeec23d3445b59293bd932b883e554f60e
5
5
  SHA512:
6
- metadata.gz: 0fa8f50e4f9326ffca33ef0a5841cacbe2cc32a2573a6f380c47159aa9c8c21a9246a970cbc85dbad0ae6d9a0eb858eef1bb4eadfc2d6c55e551a90a7f41d40b
7
- data.tar.gz: 8527fb6abb8a3a7bb0c9eb2aecbc40b239141b0517738091a01ab7d87e193abbd486b8eb2587f9cf52832ed43cd0afeb5530236a377b2d1fcc76b57e3b95922a
6
+ metadata.gz: 65ed68e2a634ec632e316f1ea4f180b7dbc19d2fb7770ddf7a541d48a6a6470a09855911162d0dd295f0ac0b3fe0efa50cee58cfbf4e796c96dd6dd9dddd77ea
7
+ data.tar.gz: 6816521a818a22ffadbea061198c0c0b79a7a07e06aff1cd2f86cea2f45fc3eba6a37f88cc15a4f5aa6c828eefaf01bb5a9a6595b202a3ff07e0052f80bca22d
data/.rubocop.yml CHANGED
@@ -76,7 +76,7 @@ Layout/DotPosition:
76
76
  # so that code can be copied to console
77
77
  EnforcedStyle: trailing
78
78
 
79
- Layout/IndentHash:
79
+ Layout/IndentFirstHashElement:
80
80
  EnforcedStyle: consistent
81
81
 
82
82
  Layout/EmptyLines:
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ sudo: false
3
3
  language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
- - 2.3.1
7
- - 2.4.1
6
+ - 2.3
7
+ - 2.5
8
+ - 2.6
8
9
  before_install: gem install bundler -v 1.16.6
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.5)
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.5.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.1)
18
- faraday (0.15.3)
17
+ docile (1.3.2)
18
+ faraday (0.15.4)
19
19
  multipart-post (>= 1.2, < 3)
20
- faraday_middleware (0.12.2)
20
+ faraday_middleware (0.13.1)
21
21
  faraday (>= 0.7.4, < 1.0)
22
- hashdiff (0.3.7)
23
- jaro_winkler (1.5.1)
24
- json (2.1.0)
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.0.0)
28
- parallel (1.12.1)
29
- parser (2.5.1.0)
27
+ multipart-post (2.1.1)
28
+ parallel (1.17.0)
29
+ parser (2.6.3.0)
30
30
  ast (~> 2.4.0)
31
- powerpack (0.1.2)
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.7.0)
36
- rspec-core (~> 3.7.0)
37
- rspec-expectations (~> 3.7.0)
38
- rspec-mocks (~> 3.7.0)
39
- rspec-core (3.7.1)
40
- rspec-support (~> 3.7.0)
41
- rspec-expectations (3.7.0)
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.7.0)
44
- rspec-mocks (3.7.0)
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.7.0)
47
- rspec-support (3.7.1)
48
- rubocop (0.57.2)
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.5)
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 (~> 1.0, >= 1.0.1)
56
- ruby-progressbar (1.9.0)
57
- safe_yaml (1.0.4)
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.4.0)
64
- webmock (3.4.2)
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.16.6
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
- Note: This is a Work-in-progress. API might change in the future.
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
- Все стандартно. Пишем в Gemfile:
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
- Пока не понятно, почему в API не все значения поля tax соответствуют цифрам в `taxNSum`, поэтому коррекцию, видимо, лучше бить через саппорт или подобным образом.
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.params.keys.each do |param|
48
- if (v = hash[param] || hash[param.to_sym])
49
- key.send(:"#{param}=", OpenSSL::BN.new(Base64.decode64(v), 2))
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)
@@ -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]/, ''),