atol 0.8.1 → 1.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 +4 -4
- data/Gemfile.lock +4 -4
- data/README.md +40 -58
- data/atol-rb.gemspec +2 -2
- data/lib/atol/config.rb +2 -1
- data/lib/atol/request/post_document/item/body.rb +13 -71
- data/lib/atol/request/post_document/item/v4/body.rb +98 -0
- data/lib/atol/request/post_document/item/v5/body.rb +101 -0
- data/lib/atol/request/post_document/sell/body.rb +1 -8
- data/lib/atol/request/post_document.rb +3 -1
- data/lib/atol/transaction/get_document_state.rb +1 -1
- data/lib/atol/transaction/post_document.rb +1 -1
- data/lib/atol/version.rb +7 -2
- metadata +12 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4959c1454e46f59413f73210058077f89a59eb076d698d1b9b18d3fe9c5df262
|
|
4
|
+
data.tar.gz: 82ecf864b3a298e28e96c845177809e9a11a72be7e27feedd05c95a6b86a3452
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee8fbffc698f9f766c57d9d2651ff66763841c683e8d1a082664cf9b82b222ccc11cda53bfca79561f33009a9caac566cb1e13e64613ed18c4abb2dbb3e98af1
|
|
7
|
+
data.tar.gz: 4bc13aae1a3a6a0b5942c1de81dd724ca496289c584254fc622b103fabb1834471c9b7c01bc065f5f880cdbfcda30c2752172dde4f7e661c51ec5674d6b0102d
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
atol (
|
|
4
|
+
atol (1.1.0)
|
|
5
5
|
anyway_config (~> 1.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
@@ -9,7 +9,7 @@ GEM
|
|
|
9
9
|
specs:
|
|
10
10
|
addressable (2.5.2)
|
|
11
11
|
public_suffix (>= 2.0.2, < 4.0)
|
|
12
|
-
anyway_config (1.
|
|
12
|
+
anyway_config (1.4.4)
|
|
13
13
|
ast (2.4.1)
|
|
14
14
|
coveralls (0.8.21)
|
|
15
15
|
json (>= 1.8, < 3)
|
|
@@ -22,7 +22,7 @@ GEM
|
|
|
22
22
|
diff-lcs (1.3)
|
|
23
23
|
docile (1.1.5)
|
|
24
24
|
hashdiff (0.3.7)
|
|
25
|
-
json (2.1
|
|
25
|
+
json (2.18.1)
|
|
26
26
|
parallel (1.19.2)
|
|
27
27
|
parser (2.7.1.4)
|
|
28
28
|
ast (~> 2.4.1)
|
|
@@ -77,7 +77,7 @@ PLATFORMS
|
|
|
77
77
|
|
|
78
78
|
DEPENDENCIES
|
|
79
79
|
atol!
|
|
80
|
-
bundler (~> 1.
|
|
80
|
+
bundler (~> 2.1.4)
|
|
81
81
|
coveralls
|
|
82
82
|
rake (~> 13.0)
|
|
83
83
|
rspec (~> 3.0)
|
data/README.md
CHANGED
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
##### Совместимость
|
|
11
11
|
|
|
12
|
-
Для корректной работы необходим интерпретатор Руби версии
|
|
13
|
-
|
|
12
|
+
Для корректной работы необходим интерпретатор Руби версии ~> 3.0.0. Пакет работает с версиями протокола [v4](http://atol.online/api_v4) и [v5](http://atol.online/api_v5) (см. настройку ATOL_API_URL).
|
|
14
13
|
|
|
15
14
|
## Использование
|
|
16
15
|
|
|
@@ -26,58 +25,10 @@ gem 'atol'
|
|
|
26
25
|
```
|
|
27
26
|
$ bundle install
|
|
28
27
|
```
|
|
29
|
-
### Конфигурация
|
|
30
|
-
|
|
31
|
-
Для обращения к сервису необходимы данные учетной записи.
|
|
32
|
-
|
|
33
|
-
При инициализации приложение попытается найти необходимые параметры в константе `ENV`.
|
|
34
|
-
|
|
35
|
-
Для корректной работы потребуются следующие переменные окружения.
|
|
36
|
-
|
|
37
|
-
**Все переменные являются обязательными**.
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# .env
|
|
41
|
-
ATOL_INN=123456789010
|
|
42
|
-
ATOL_LOGIN=example-login
|
|
43
|
-
ATOL_PASSWORD=example-password
|
|
44
|
-
ATOL_PAYMENT_ADDRESS="г. Москва, ул. Ленина, д.1 к.2"
|
|
45
|
-
ATOL_GROUP_CODE=example-group-code
|
|
46
|
-
ATOL_DEFAULT_SNO=esn
|
|
47
|
-
ATOL_DEFAULT_TAX=vat18
|
|
48
|
-
ATOL_CALLBACK_URL=https://www.example.com/callback_path
|
|
49
|
-
ATOL_COMPANY_EMAIL=example@email.com
|
|
50
|
-
ATOL_DEFAULT_PAYMENT_TYPE=1
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Значения `ATOL_INN`, `ATOL_LOGIN`, `ATOL_PASSWORD`, `ATOL_PAYMENT_ADDRESS` и `ATOL_GROUP_CODE` вы получаете при регистрации в сервисе.
|
|
54
|
-
|
|
55
|
-
`ATOL_DEFAULT_SNO` - система налогообложения. Возможные значения:
|
|
56
|
-
1) "osn" – общая СН;
|
|
57
|
-
2) "usn_income" – упрощенная СН (доходы);
|
|
58
|
-
3) "usn_income_outcome" – упрощенная СН (доходы минус расходы);
|
|
59
|
-
4) "envd" – единый налог на вмененный доход;
|
|
60
|
-
5) "esn" – единый сельскохозяйственный налог;
|
|
61
|
-
6) "patent" – патентная СН.
|
|
62
|
-
|
|
63
|
-
`ATOL_DEFAULT_TAX` - номер налога в ККТ. Возможные значения:
|
|
64
|
-
1) "none" – без НДС;
|
|
65
|
-
2) "vat0" – НДС по ставке 0%;
|
|
66
|
-
3) "vat10" – НДС чека по ставке 10%;
|
|
67
|
-
4) "vat18" – НДС чека по ставке 18%;
|
|
68
|
-
5) "vat110" – НДС чека по расчетной ставке 10/110;
|
|
69
|
-
6) "vat118" – НДС чека по расчетной ставке 18/118.
|
|
70
|
-
|
|
71
|
-
`ATOL_CALLBACK_URL` - адрес, по которому сервис будет отправлять информацию после создания чека.
|
|
72
|
-
|
|
73
|
-
`ATOL_DEFAULT_PAYMENT_TYPE` - вид оплаты. Возможные значения:
|
|
74
|
-
1) "1" – электронный;
|
|
75
|
-
2) "2" – "9" – расширенные типы оплаты. Для каждого фискального типа оплаты можно указать расширенный тип оплаты.
|
|
76
|
-
|
|
77
|
-
`ATOL_COMPANY_EMAIL` - адрес электронной почты вашей компании.
|
|
78
|
-
|
|
79
28
|
### Конфигурация в инициализаторе
|
|
80
29
|
|
|
30
|
+
Для обращения к сервису необходимы данные учетной записи. `login`, `password` и `group_code`
|
|
31
|
+
|
|
81
32
|
Для Rails-приложений так же можно создать файл инициализации и задать параметры непосредственно в коде:
|
|
82
33
|
|
|
83
34
|
```ruby
|
|
@@ -88,13 +39,15 @@ Rails.application.config.after_initialize do
|
|
|
88
39
|
config.inn = '123456789010'
|
|
89
40
|
config.login = 'example-login'
|
|
90
41
|
config.password = 'example-password'
|
|
91
|
-
config.payment_address = 'г. Москва, ул. Ленина, д.1 к.2'
|
|
42
|
+
config.payment_address = 'г. Москва, ул. Ленина, д.1 к.2' # тэг 1187
|
|
92
43
|
config.group_code = 'example-group-code'
|
|
93
|
-
config.default_sno = 'esn'
|
|
44
|
+
config.default_sno = 'esn' # тэг 1055
|
|
94
45
|
config.default_tax = 'vat18'
|
|
95
46
|
config.callback_url = 'https://www.example.com/callback_path'
|
|
96
47
|
config.company_email = 'example@email.com'
|
|
97
|
-
config.default_payment_type = '1'
|
|
48
|
+
config.default_payment_type = '1' # тэг 1031
|
|
49
|
+
config.api_url = 'https://online.atol.ru/possystem/v5' # по умолчанию 'https://online.atol.ru/possystem/v4' ФФД 1.05
|
|
50
|
+
config.internet = true # тэг 1125, по умолчанию false
|
|
98
51
|
end
|
|
99
52
|
end
|
|
100
53
|
```
|
|
@@ -151,8 +104,7 @@ body = Atol::Request::PostDocument::Sell::Body.new(
|
|
|
151
104
|
email: 'example@example.com',
|
|
152
105
|
items: [
|
|
153
106
|
...
|
|
154
|
-
]
|
|
155
|
-
agent_info_type: 'bank_paying_agent'
|
|
107
|
+
]
|
|
156
108
|
).to_json
|
|
157
109
|
```
|
|
158
110
|
|
|
@@ -160,6 +112,8 @@ body = Atol::Request::PostDocument::Sell::Body.new(
|
|
|
160
112
|
|
|
161
113
|
Массив `items` должен включать в себя объекты, которые так же соответствуют схеме.
|
|
162
114
|
|
|
115
|
+
#### Items для версии V4
|
|
116
|
+
|
|
163
117
|
Для создания `items` можно использовать класс `Atol::Request::PostDocument::Item::Body`.
|
|
164
118
|
|
|
165
119
|
Его конструктор принимает обязательные аргументы `name`, `price`, `payment_method`, `payment_object` и опциональные `quantity` (по умолчанию 1), `supplier_info_inn`, `supplier_info_name`, `agent_info_type` (тег ФФД - 1222).
|
|
@@ -197,7 +151,7 @@ item = Atol::Request::PostDocument::Item::Body.new(
|
|
|
197
151
|
Тогда создание всего тела запроса будет выглядеть так:
|
|
198
152
|
|
|
199
153
|
```ruby
|
|
200
|
-
|
|
154
|
+
Atol::Request::PostDocument::Sell::Body.new(
|
|
201
155
|
external_id: 123,
|
|
202
156
|
email: 'example@example.com',
|
|
203
157
|
items: [
|
|
@@ -271,8 +225,36 @@ body = Atol::Request::PostDocument::Sell::Body.new(
|
|
|
271
225
|
"timestamp":"06.02.2018 12:35:00",
|
|
272
226
|
"external_id":123
|
|
273
227
|
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### Items для версии V5
|
|
231
|
+
|
|
232
|
+
Создается как в v4 только
|
|
233
|
+
|
|
234
|
+
- Добавлено обязательное поле `measure`
|
|
235
|
+
- Добавлено обязательное поле `vat`
|
|
236
|
+
- Изменен тип поля `payment_object` на int
|
|
237
|
+
|
|
238
|
+
Доступные значения для `measure`
|
|
274
239
|
|
|
275
240
|
```
|
|
241
|
+
0, 10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 70, 71, 72, 73, 80, 81, 82, 83, 255
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`vat` имеет вид объекта, пример
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
{ type: 'none' }
|
|
248
|
+
```
|
|
249
|
+
Доступные type для vat
|
|
250
|
+
`none vat0 vat5 vat7 vat10 vat22 vat105 vat107 vat110 vat20 vat120 vat122`
|
|
251
|
+
|
|
252
|
+
Доступные значения для `payment_object`
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
|
|
256
|
+
```
|
|
257
|
+
|
|
276
258
|
#### Отправка документа
|
|
277
259
|
|
|
278
260
|
Когда токен и тело запроса составлены, остается только сделать post-запрос.
|
data/atol-rb.gemspec
CHANGED
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.summary = 'ATOL KaaS client for Ruby'
|
|
14
14
|
spec.homepage = 'https://github.com/sputnik8/atol-rb'
|
|
15
15
|
spec.license = 'MIT'
|
|
16
|
-
spec.required_ruby_version = '>=
|
|
16
|
+
spec.required_ruby_version = '>= 3.0.0'
|
|
17
17
|
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
19
19
|
f.match(%r{^(test|spec|features)/})
|
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
|
|
26
26
|
spec.add_dependency 'anyway_config', '~> 1.0'
|
|
27
27
|
|
|
28
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
|
28
|
+
spec.add_development_dependency 'bundler', '~> 2.1.4'
|
|
29
29
|
spec.add_development_dependency 'rake', '~> 13.0'
|
|
30
30
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
|
31
31
|
spec.add_development_dependency 'rubocop', '~> 0.90'
|
data/lib/atol/config.rb
CHANGED
|
@@ -15,9 +15,10 @@ module Atol
|
|
|
15
15
|
:default_tax,
|
|
16
16
|
:callback_url,
|
|
17
17
|
:company_email,
|
|
18
|
+
internet: false,
|
|
18
19
|
req_tries_number: 3,
|
|
19
20
|
default_payment_type: 1,
|
|
20
21
|
http_client: Net::HTTP,
|
|
21
|
-
api_url:
|
|
22
|
+
api_url: Atol::Version::V4
|
|
22
23
|
end
|
|
23
24
|
end
|
|
@@ -1,86 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'atol/errors'
|
|
4
|
-
|
|
5
3
|
module Atol
|
|
6
4
|
module Request
|
|
7
5
|
class PostDocument
|
|
8
6
|
module Item
|
|
9
7
|
class Body
|
|
10
|
-
|
|
11
|
-
BadPaymentObjectError = Class.new(StandardError)
|
|
12
|
-
|
|
13
|
-
PAYMENT_METHODS = [
|
|
14
|
-
'full_prepayment', 'prepayment', 'advance', 'full_payment',
|
|
15
|
-
'partial_payment', 'credit', 'credit_payment'
|
|
16
|
-
]
|
|
17
|
-
|
|
18
|
-
PAYMENT_OBJECTS = [
|
|
19
|
-
'commodity', 'excise', 'job', 'service', 'gambling_bet', 'gambling_prize',
|
|
20
|
-
'lottery', 'lottery_prize', 'intellectual_activity', 'payment', 'agent_commission',
|
|
21
|
-
'composite', 'another'
|
|
22
|
-
]
|
|
8
|
+
BadApiUrlError = Class.new(StandardError)
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
:agent_info_type, :supplier_info_inn, :supplier_info_name
|
|
10
|
+
attr_reader :instance
|
|
26
11
|
|
|
27
|
-
def initialize(
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
def initialize(**kwargs)
|
|
13
|
+
config = kwargs[:config] || Atol.config
|
|
14
|
+
@instance = case config.api_url
|
|
15
|
+
when Atol::Version::V4, Atol::Version::V4_TEST
|
|
16
|
+
Atol::Request::PostDocument::Item::V4::Body.new(**kwargs)
|
|
17
|
+
when Atol::Version::V5, Atol::Version::V5_TEST
|
|
18
|
+
Atol::Request::PostDocument::Item::V5::Body.new(**kwargs)
|
|
19
|
+
else
|
|
20
|
+
raise BadApiUrlError
|
|
21
|
+
end
|
|
30
22
|
end
|
|
31
23
|
|
|
32
24
|
def to_h
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def to_json(*_args)
|
|
37
|
-
body.to_json
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def setup_attributes(config, name, price, quantity, payment_method, payment_object, options)
|
|
43
|
-
self.config = config || Atol.config
|
|
44
|
-
self.name = name
|
|
45
|
-
self.price = price.to_f
|
|
46
|
-
self.quantity = quantity.to_f
|
|
47
|
-
self.payment_method = payment_method.to_s
|
|
48
|
-
self.payment_object = payment_object.to_s
|
|
49
|
-
self.agent_info_type = options[:agent_info_type].to_s
|
|
50
|
-
self.supplier_info_inn = options[:supplier_info_inn].to_s
|
|
51
|
-
self.supplier_info_name = options[:supplier_info_name].to_s
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def validate_attributes
|
|
55
|
-
raise Atol::ZeroItemQuantityError if quantity.to_f.zero?
|
|
56
|
-
raise BadPaymentMethodError unless PAYMENT_METHODS.include?(payment_method)
|
|
57
|
-
raise BadPaymentObjectError unless PAYMENT_OBJECTS.include?(payment_object)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def agent_info
|
|
61
|
-
return if agent_info_type.nil? || agent_info_type.empty?
|
|
62
|
-
|
|
63
|
-
{ agent_info: { type: agent_info_type } }
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def supplier_info
|
|
67
|
-
return if supplier_info_inn.nil? || supplier_info_inn.empty? || agent_info.nil?
|
|
68
|
-
|
|
69
|
-
info = { inn: supplier_info_inn, name: supplier_info_name }
|
|
70
|
-
filtered_info = info.reject { |_key, value| value&.empty? }
|
|
71
|
-
{ supplier_info: filtered_info } unless filtered_info.empty?
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def body
|
|
75
|
-
@body ||= {
|
|
76
|
-
name: name,
|
|
77
|
-
price: price,
|
|
78
|
-
quantity: quantity,
|
|
79
|
-
sum: (price * quantity).round(2),
|
|
80
|
-
tax: config.default_tax,
|
|
81
|
-
payment_method: payment_method,
|
|
82
|
-
payment_object: payment_object
|
|
83
|
-
}.merge(supplier_info.to_h, agent_info.to_h)
|
|
25
|
+
instance.to_h
|
|
84
26
|
end
|
|
85
27
|
end
|
|
86
28
|
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atol/errors'
|
|
4
|
+
|
|
5
|
+
module Atol
|
|
6
|
+
module Request
|
|
7
|
+
class PostDocument
|
|
8
|
+
module Item
|
|
9
|
+
module V4
|
|
10
|
+
class Body
|
|
11
|
+
BadPaymentMethodError = Class.new(StandardError)
|
|
12
|
+
BadPaymentObjectError = Class.new(StandardError)
|
|
13
|
+
|
|
14
|
+
PAYMENT_METHODS = %w[
|
|
15
|
+
full_prepayment prepayment advance full_payment
|
|
16
|
+
partial_payment credit credit_payment
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
PAYMENT_OBJECTS = %w[
|
|
20
|
+
commodity excise job service gambling_bet gambling_prize
|
|
21
|
+
lottery lottery_prize intellectual_activity payment agent_commission
|
|
22
|
+
composite another
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
attr_accessor :config,
|
|
26
|
+
:name,
|
|
27
|
+
:price,
|
|
28
|
+
:quantity,
|
|
29
|
+
:payment_method,
|
|
30
|
+
:payment_object,
|
|
31
|
+
:agent_info_type,
|
|
32
|
+
:supplier_info_inn,
|
|
33
|
+
:supplier_info_name
|
|
34
|
+
|
|
35
|
+
def initialize(config: nil, name:, price:, quantity: 1, payment_method:, payment_object:, **options)
|
|
36
|
+
setup_attributes(config, name, price, quantity, payment_method, payment_object, options)
|
|
37
|
+
validate_attributes
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def to_h
|
|
41
|
+
body.clone
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_json(*_args)
|
|
45
|
+
body.to_json
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def setup_attributes(config, name, price, quantity, payment_method, payment_object, options)
|
|
51
|
+
self.config = config || Atol.config
|
|
52
|
+
self.name = name
|
|
53
|
+
self.price = price.to_f
|
|
54
|
+
self.quantity = quantity.to_f
|
|
55
|
+
self.payment_method = payment_method.to_s
|
|
56
|
+
self.payment_object = payment_object.to_s
|
|
57
|
+
self.agent_info_type = options[:agent_info_type].to_s
|
|
58
|
+
self.supplier_info_inn = options[:supplier_info_inn].to_s
|
|
59
|
+
self.supplier_info_name = options[:supplier_info_name].to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def validate_attributes
|
|
63
|
+
raise Atol::ZeroItemQuantityError if quantity.to_f.zero?
|
|
64
|
+
raise BadPaymentMethodError unless PAYMENT_METHODS.include?(payment_method)
|
|
65
|
+
raise BadPaymentObjectError unless PAYMENT_OBJECTS.include?(payment_object)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def agent_info
|
|
69
|
+
return if agent_info_type.nil? || agent_info_type.empty?
|
|
70
|
+
|
|
71
|
+
{ agent_info: { type: agent_info_type } }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def supplier_info
|
|
75
|
+
return if supplier_info_inn.nil? || supplier_info_inn.empty? || agent_info.nil?
|
|
76
|
+
|
|
77
|
+
info = { inn: supplier_info_inn, name: supplier_info_name }
|
|
78
|
+
filtered_info = info.reject { |_key, value| value&.empty? }
|
|
79
|
+
{ supplier_info: filtered_info } unless filtered_info.empty?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def body
|
|
83
|
+
@body ||= {
|
|
84
|
+
name: name,
|
|
85
|
+
price: price,
|
|
86
|
+
quantity: quantity,
|
|
87
|
+
sum: (price * quantity).round(2),
|
|
88
|
+
tax: config.default_tax,
|
|
89
|
+
payment_method: payment_method,
|
|
90
|
+
payment_object: payment_object
|
|
91
|
+
}.merge(supplier_info.to_h, agent_info.to_h)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'atol/errors'
|
|
4
|
+
|
|
5
|
+
module Atol
|
|
6
|
+
module Request
|
|
7
|
+
class PostDocument
|
|
8
|
+
module Item
|
|
9
|
+
module V5
|
|
10
|
+
class Body
|
|
11
|
+
BadPaymentMethodError = Class.new(StandardError)
|
|
12
|
+
BadPaymentObjectError = Class.new(StandardError)
|
|
13
|
+
BadMeasureError = Class.new(StandardError)
|
|
14
|
+
BadVatTypeError = Class.new(StandardError)
|
|
15
|
+
|
|
16
|
+
# https://atol-kassa.ru/wp-content/nfiles/files/ATOL/kassa/АТОЛ%20Онлайн%20-%20Описание%20протокола%20v5%20(ФФД%201.2).pdf
|
|
17
|
+
|
|
18
|
+
PAYMENT_METHODS = %w[full_prepayment prepayment advance full_payment partial_payment credit credit_payment].freeze
|
|
19
|
+
PAYMENT_OBJECTS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].freeze
|
|
20
|
+
MEASURE = [0, 10, 11, 12, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 70, 71, 72, 73, 80, 81, 82, 83, 255].freeze
|
|
21
|
+
VAT_TYPES = %w[none vat0 vat5 vat7 vat10 vat22 vat105 vat107 vat110 vat20 vat120 vat122].freeze
|
|
22
|
+
|
|
23
|
+
attr_accessor :name,
|
|
24
|
+
:price,
|
|
25
|
+
:quantity,
|
|
26
|
+
:payment_method,
|
|
27
|
+
:payment_object,
|
|
28
|
+
:agent_info_type,
|
|
29
|
+
:supplier_info_inn,
|
|
30
|
+
:supplier_info_name,
|
|
31
|
+
:measure,
|
|
32
|
+
:vat
|
|
33
|
+
|
|
34
|
+
def initialize(name:, price:, quantity: 1, payment_method:, payment_object:, measure:, vat:, **options)
|
|
35
|
+
setup_attributes(name, price, quantity, payment_method, payment_object, measure, vat, options)
|
|
36
|
+
validate_attributes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def to_h
|
|
40
|
+
body.clone
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_json(*_args)
|
|
44
|
+
body.to_json
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def setup_attributes(name, price, quantity, payment_method, payment_object, measure, vat, options)
|
|
50
|
+
self.name = name
|
|
51
|
+
self.price = price.to_f
|
|
52
|
+
self.quantity = quantity.to_f
|
|
53
|
+
self.payment_method = payment_method.to_s
|
|
54
|
+
self.payment_object = payment_object
|
|
55
|
+
self.agent_info_type = options[:agent_info_type].to_s
|
|
56
|
+
self.supplier_info_inn = options[:supplier_info_inn].to_s
|
|
57
|
+
self.supplier_info_name = options[:supplier_info_name].to_s
|
|
58
|
+
self.measure = measure
|
|
59
|
+
self.vat = vat
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def validate_attributes
|
|
63
|
+
raise Atol::ZeroItemQuantityError if quantity.to_f.zero?
|
|
64
|
+
raise BadPaymentMethodError unless PAYMENT_METHODS.include?(payment_method)
|
|
65
|
+
raise BadPaymentObjectError unless PAYMENT_OBJECTS.include?(payment_object)
|
|
66
|
+
raise BadMeasureError unless MEASURE.include?(measure)
|
|
67
|
+
raise BadVatTypeError unless VAT_TYPES.include?(vat&.[](:type))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def agent_info
|
|
71
|
+
return if agent_info_type.nil? || agent_info_type.empty?
|
|
72
|
+
|
|
73
|
+
{ agent_info: { type: agent_info_type } }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def supplier_info
|
|
77
|
+
return if supplier_info_inn.nil? || supplier_info_inn.empty? || agent_info.nil?
|
|
78
|
+
|
|
79
|
+
info = { inn: supplier_info_inn, name: supplier_info_name }
|
|
80
|
+
filtered_info = info.reject { |_key, value| value&.empty? }
|
|
81
|
+
{ supplier_info: filtered_info } unless filtered_info.empty?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def body
|
|
85
|
+
@body ||= {
|
|
86
|
+
name: name,
|
|
87
|
+
price: price,
|
|
88
|
+
quantity: quantity,
|
|
89
|
+
sum: (price * quantity).round(2),
|
|
90
|
+
payment_method: payment_method,
|
|
91
|
+
payment_object: payment_object,
|
|
92
|
+
measure: measure,
|
|
93
|
+
vat: vat
|
|
94
|
+
}.merge(supplier_info.to_h, agent_info.to_h)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -16,7 +16,6 @@ module Atol
|
|
|
16
16
|
@phone = phone
|
|
17
17
|
@email = email
|
|
18
18
|
@items = items
|
|
19
|
-
@agent_info_type = options[:agent_info_type]
|
|
20
19
|
end
|
|
21
20
|
|
|
22
21
|
def to_h
|
|
@@ -73,13 +72,7 @@ module Atol
|
|
|
73
72
|
def add_receipt_data(receipt)
|
|
74
73
|
receipt[:total] = receipt[:payments][0][:sum] = total
|
|
75
74
|
receipt[:items] = @items
|
|
76
|
-
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def add_agent_and_supplier_info(receipt)
|
|
80
|
-
return if @agent_info_type.nil? || @agent_info_type.empty?
|
|
81
|
-
|
|
82
|
-
receipt[:agent_info] = { type: @agent_info_type }
|
|
75
|
+
receipt[:internet] = @config.internet
|
|
83
76
|
end
|
|
84
77
|
|
|
85
78
|
def total
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
require 'atol'
|
|
4
4
|
require 'atol/errors'
|
|
5
5
|
require 'atol/request/post_document/item/body'
|
|
6
|
+
require 'atol/request/post_document/item/v4/body'
|
|
7
|
+
require 'atol/request/post_document/item/v5/body'
|
|
6
8
|
require 'atol/request/post_document/sell/body'
|
|
7
9
|
|
|
8
10
|
module Atol
|
|
9
11
|
module Request
|
|
10
12
|
class PostDocument
|
|
11
|
-
OPERATIONS = %i[sell sell_refund sell_correction buy buy_refund buy_correction].freeze
|
|
13
|
+
OPERATIONS = %i[sell sell_refund sell_correction sell_refund_correction buy buy_refund buy_correction buy_refund_correction].freeze
|
|
12
14
|
HEADERS = { 'Content-Type' => 'application/json; charset=utf-8' }.freeze
|
|
13
15
|
|
|
14
16
|
def initialize(operation:, token:, body:, config: nil, req_logger: nil, res_logger: nil)
|
|
@@ -14,7 +14,7 @@ module Atol
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def call
|
|
17
|
-
request = Atol::Request::GetDocumentState.new(
|
|
17
|
+
request = Atol::Request::GetDocumentState.new(**@params)
|
|
18
18
|
response = request.call
|
|
19
19
|
encoded_body = response.body.dup.force_encoding(Atol::ENCODING)
|
|
20
20
|
json = JSON.parse(encoded_body)
|
|
@@ -21,7 +21,7 @@ module Atol
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def call
|
|
24
|
-
request = Atol::Request::PostDocument.new(
|
|
24
|
+
request = Atol::Request::PostDocument.new(**@params)
|
|
25
25
|
response = request.call
|
|
26
26
|
encoded_body = response.body.dup.force_encoding(Atol::ENCODING)
|
|
27
27
|
json = JSON.parse(encoded_body)
|
data/lib/atol/version.rb
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Atol
|
|
4
4
|
module Version
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
V4 = 'https://online.atol.ru/possystem/v4'
|
|
6
|
+
V5 = 'https://online.atol.ru/possystem/v5'
|
|
7
|
+
|
|
8
|
+
V4_TEST = 'https://testonline.atol.ru/possystem/v4'
|
|
9
|
+
V5_TEST = 'https://testonline.atol.ru/possystem/v5'
|
|
10
|
+
|
|
11
|
+
LIB = '1.1.0'
|
|
7
12
|
end
|
|
8
13
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atol
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GeorgeGorbanev
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-04-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: anyway_config
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 2.1.4
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 2.1.4
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: rake
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,7 +94,7 @@ dependencies:
|
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '3.0'
|
|
97
|
-
description:
|
|
97
|
+
description:
|
|
98
98
|
email:
|
|
99
99
|
- GeorgeGorbanev@gmail.com
|
|
100
100
|
executables: []
|
|
@@ -120,6 +120,8 @@ files:
|
|
|
120
120
|
- lib/atol/request/get_token.rb
|
|
121
121
|
- lib/atol/request/post_document.rb
|
|
122
122
|
- lib/atol/request/post_document/item/body.rb
|
|
123
|
+
- lib/atol/request/post_document/item/v4/body.rb
|
|
124
|
+
- lib/atol/request/post_document/item/v5/body.rb
|
|
123
125
|
- lib/atol/request/post_document/sell/body.rb
|
|
124
126
|
- lib/atol/transaction.rb
|
|
125
127
|
- lib/atol/transaction/get_document_state.rb
|
|
@@ -130,7 +132,7 @@ homepage: https://github.com/sputnik8/atol-rb
|
|
|
130
132
|
licenses:
|
|
131
133
|
- MIT
|
|
132
134
|
metadata: {}
|
|
133
|
-
post_install_message:
|
|
135
|
+
post_install_message:
|
|
134
136
|
rdoc_options: []
|
|
135
137
|
require_paths:
|
|
136
138
|
- lib
|
|
@@ -138,15 +140,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
138
140
|
requirements:
|
|
139
141
|
- - ">="
|
|
140
142
|
- !ruby/object:Gem::Version
|
|
141
|
-
version:
|
|
143
|
+
version: 3.0.0
|
|
142
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
145
|
requirements:
|
|
144
146
|
- - ">="
|
|
145
147
|
- !ruby/object:Gem::Version
|
|
146
148
|
version: '0'
|
|
147
149
|
requirements: []
|
|
148
|
-
rubygems_version: 3.
|
|
149
|
-
signing_key:
|
|
150
|
+
rubygems_version: 3.2.33
|
|
151
|
+
signing_key:
|
|
150
152
|
specification_version: 4
|
|
151
153
|
summary: ATOL KaaS client for Ruby
|
|
152
154
|
test_files: []
|