fakturoid 0.5.0 → 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/.rubocop.yml +6 -10
- data/.ruby-version +1 -1
- data/CHANGELOG.md +15 -0
- data/README.md +540 -145
- data/Rakefile +3 -1
- data/fakturoid.gemspec +36 -25
- data/lib/fakturoid/api/account.rb +13 -0
- data/lib/fakturoid/api/bank_account.rb +13 -0
- data/lib/fakturoid/api/base.rb +18 -0
- data/lib/fakturoid/api/event.rb +23 -0
- data/lib/fakturoid/api/expense.rb +55 -0
- data/lib/fakturoid/api/expense_payment.rb +20 -0
- data/lib/fakturoid/api/generator.rb +36 -0
- data/lib/fakturoid/api/inbox_file.rb +34 -0
- data/lib/fakturoid/api/inventory_item.rb +66 -0
- data/lib/fakturoid/api/inventory_move.rb +40 -0
- data/lib/fakturoid/api/invoice.rb +62 -0
- data/lib/fakturoid/api/invoice_message.rb +14 -0
- data/lib/fakturoid/api/invoice_payment.rb +26 -0
- data/lib/fakturoid/api/number_format.rb +13 -0
- data/lib/fakturoid/api/recurring_generator.rb +36 -0
- data/lib/fakturoid/api/subject.rb +42 -0
- data/lib/fakturoid/api/todo.rb +20 -0
- data/lib/fakturoid/api/user.rb +17 -0
- data/lib/fakturoid/api/webhook.rb +34 -0
- data/lib/fakturoid/api.rb +89 -9
- data/lib/fakturoid/client.rb +46 -12
- data/lib/fakturoid/config.rb +69 -12
- data/lib/fakturoid/oauth/access_token_service.rb +46 -0
- data/lib/fakturoid/oauth/credentials.rb +63 -0
- data/lib/fakturoid/oauth/flow/authorization_code.rb +53 -0
- data/lib/fakturoid/oauth/flow/base.rb +42 -0
- data/lib/fakturoid/oauth/flow/client_credentials.rb +27 -0
- data/lib/fakturoid/oauth/flow.rb +5 -0
- data/lib/fakturoid/oauth/request/api.rb +11 -0
- data/lib/fakturoid/oauth/request/base.rb +60 -0
- data/lib/fakturoid/oauth/request/oauth.rb +24 -0
- data/lib/fakturoid/oauth/request.rb +5 -0
- data/lib/fakturoid/oauth/token_response.rb +56 -0
- data/lib/fakturoid/oauth.rb +39 -0
- data/lib/fakturoid/response.rb +8 -20
- data/lib/fakturoid/utils.rb +27 -0
- data/lib/fakturoid/version.rb +1 -1
- data/lib/fakturoid.rb +22 -22
- metadata +48 -53
- data/.github/workflows/rubocop.yml +0 -20
- data/.github/workflows/tests.yml +0 -27
- data/.gitignore +0 -7
- data/Gemfile +0 -6
- data/lib/fakturoid/api/arguments.rb +0 -21
- data/lib/fakturoid/api/http_methods.rb +0 -23
- data/lib/fakturoid/client/account.rb +0 -11
- data/lib/fakturoid/client/bank_account.rb +0 -11
- data/lib/fakturoid/client/event.rb +0 -19
- data/lib/fakturoid/client/expense.rb +0 -49
- data/lib/fakturoid/client/generator.rb +0 -44
- data/lib/fakturoid/client/inventory_items.rb +0 -59
- data/lib/fakturoid/client/inventory_moves.rb +0 -36
- data/lib/fakturoid/client/invoice.rb +0 -73
- data/lib/fakturoid/client/number_format.rb +0 -11
- data/lib/fakturoid/client/subject.rb +0 -41
- data/lib/fakturoid/client/todo.rb +0 -18
- data/lib/fakturoid/client/user.rb +0 -20
- data/lib/fakturoid/connection.rb +0 -30
- data/lib/fakturoid/request.rb +0 -31
- data/test/api_test.rb +0 -24
- data/test/config_test.rb +0 -40
- data/test/fixtures/blocked_account.json +0 -8
- data/test/fixtures/invoice.json +0 -81
- data/test/fixtures/invoice.pdf +0 -0
- data/test/fixtures/invoice_error.json +0 -7
- data/test/fixtures/subjects.json +0 -52
- data/test/request_test.rb +0 -20
- data/test/response_test.rb +0 -189
- data/test/test_helper.rb +0 -19
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Fakturoid
|
2
2
|
|
3
|
-
The Fakturoid gem is
|
4
|
-
|
3
|
+
The Fakturoid gem is Ruby library for API communication with web based invoicing service [www.fakturoid.cz](https://www.fakturoid.cz/).
|
4
|
+
|
5
|
+
Fakturoid [API documentation](https://www.fakturoid.cz/api/v3).
|
5
6
|
|
6
7
|
[](http://badge.fury.io/rb/fakturoid)
|
7
8
|
[](https://github.com/fakturoid/fakturoid-ruby/actions/workflows/tests.yml)
|
@@ -17,148 +18,260 @@ gem "fakturoid"
|
|
17
18
|
|
18
19
|
And then run:
|
19
20
|
|
20
|
-
|
21
|
+
```sh
|
22
|
+
bundle
|
23
|
+
```
|
24
|
+
|
25
|
+
## Gem Versions
|
26
|
+
|
27
|
+
| Gem version | Fakturoid API | Supported Ruby |
|
28
|
+
|-------------|---------------------------------------------|----------------|
|
29
|
+
| `1.x` | [API v3](https://www.fakturoid.cz/api/v3) | `>=2.7.0` |
|
30
|
+
| `0.x` | [API v2](https://fakturoid.docs.apiary.io/) | `>=2.7.0` |
|
21
31
|
|
22
32
|
## Configuration
|
23
33
|
|
24
|
-
|
34
|
+
### Authorization with OAuth 2.0
|
35
|
+
|
36
|
+
#### Authorization Code Flow
|
37
|
+
|
38
|
+
Authorization using OAuth takes place in several steps. We use data obtained from the developer portal as client ID and
|
39
|
+
client secret (Settings → Connect other apps → OAuth 2 for app developers).
|
40
|
+
|
41
|
+
First, we offer the user a URL address where he enters his login information. We obtain this using the following method
|
42
|
+
(you can place it in an intializer `config/initializers/fakturoid.rb`):
|
25
43
|
|
26
44
|
```ruby
|
27
45
|
Fakturoid.configure do |config|
|
28
|
-
config.email
|
29
|
-
config.
|
30
|
-
config.
|
31
|
-
config.
|
46
|
+
config.email = "yourfakturoid@email.com"
|
47
|
+
config.account = "{fakturoid-account-slug}" # You can also set `account` dynamically later.
|
48
|
+
config.user_agent = "Name of your app (your@email.com)"
|
49
|
+
config.client_id = "{fakturoid-client-id}"
|
50
|
+
config.client_secret = "{fakturoid-client-secret}"
|
51
|
+
config.redirect_uri = "{your-redirect-uri}"
|
52
|
+
config.oauth_flow = "authorization_code"
|
32
53
|
end
|
33
54
|
```
|
34
55
|
|
35
|
-
|
56
|
+
Create a client and let the user come to our OAuth login page:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
client = Fakturoid.client
|
36
60
|
|
37
|
-
|
61
|
+
# To be rendered on a web page. State is optional.
|
62
|
+
link_to client.authorization_uri, "Enable Fakturoid Integration"
|
63
|
+
link_to client.authorization_uri(state: "abcd1234"), "Enable Fakturoid Integration"
|
64
|
+
```
|
38
65
|
|
39
|
-
|
66
|
+
After entering the login data, the user is redirected to the specified redirect URI and with the code with which we
|
67
|
+
obtain his credentials. We process the code as follows:
|
40
68
|
|
41
69
|
```ruby
|
42
|
-
|
43
|
-
response.status_code # returns response http code
|
44
|
-
response.body # contains hash with returned body
|
70
|
+
client.authorize(code: params[:code])
|
45
71
|
```
|
46
72
|
|
47
|
-
|
73
|
+
Credentials are now established in the object instance and we can send queries to the Fakturoid API.
|
48
74
|
|
49
75
|
```ruby
|
50
|
-
|
51
|
-
response.name # alternative way of getting the name of your company
|
76
|
+
pp client.credentials.as_json
|
52
77
|
```
|
53
78
|
|
54
|
-
|
79
|
+
Credentials can also be set manually (eg. loaded from a database):
|
55
80
|
|
56
|
-
|
81
|
+
```ruby
|
82
|
+
client.credentials = {
|
83
|
+
access_token: "1db22484a6d6256e7942158d216157d075ab6e7b583bd16416181ca6c4ac180167acd8d599bd123d", # Example
|
84
|
+
refresh_token: "5682a4bc6254d85934a03931ed5e235e0f81bca64aef054fa0049d8c953eab919ba67bd8ceb532d7",
|
85
|
+
expires_at: "2024-03-01T12:42:40+01:00", # This also accepts `Time` or `DateTime` object.
|
86
|
+
token_type: "Bearer"
|
87
|
+
}
|
88
|
+
```
|
57
89
|
|
58
|
-
|
90
|
+
Don't forget to update your credentials after an access token refresh:
|
59
91
|
|
60
92
|
```ruby
|
61
|
-
|
93
|
+
client.credentials_updated_callback do |credentials|
|
94
|
+
# Store new credentials into database.
|
95
|
+
pp client.credentials.as_json
|
96
|
+
end
|
62
97
|
```
|
63
98
|
|
64
|
-
|
99
|
+
You may need to set account slug dynamically:
|
65
100
|
|
66
101
|
```ruby
|
67
|
-
|
102
|
+
client.account = client.users.current.body["accounts"].first["slug"]
|
68
103
|
```
|
69
104
|
|
70
|
-
|
105
|
+
And if you need to create a separate client for a different account:
|
71
106
|
|
72
107
|
```ruby
|
73
|
-
|
108
|
+
client = Fakturoid::Client.new(account: "{another-fakturoid-account-slug}")
|
74
109
|
```
|
75
110
|
|
76
|
-
|
111
|
+
Revoke access altogether (works in both flows):
|
77
112
|
|
78
|
-
|
113
|
+
```ruby
|
114
|
+
client.revoke_access
|
115
|
+
```
|
79
116
|
|
80
|
-
|
117
|
+
#### Client Credentials Flow
|
81
118
|
|
82
119
|
```ruby
|
83
|
-
|
120
|
+
Fakturoid.configure do |config|
|
121
|
+
config.email = "yourfakturoid@email.com"
|
122
|
+
config.account = "{fakturoid-account-slug}"
|
123
|
+
config.user_agent = "Name of your app (your@email.com)"
|
124
|
+
config.client_id = "{fakturoid-client-id}"
|
125
|
+
config.client_secret = "{fakturoid-client-secret}"
|
126
|
+
config.oauth_flow = "client_credentials"
|
127
|
+
end
|
84
128
|
```
|
85
129
|
|
86
|
-
|
130
|
+
Credentials can be set and stored the same way as above just without a refresh token.
|
131
|
+
|
132
|
+
## Usage
|
133
|
+
|
134
|
+
Almost all resources that return a list of things are paginated by 40 per page. You can specify the page number
|
135
|
+
by passing a `page` parameter: `client.some_resource.all(page: 2)`.
|
87
136
|
|
88
|
-
###
|
137
|
+
### [User Resource](https://www.fakturoid.cz/api/v3/users)
|
89
138
|
|
90
|
-
|
139
|
+
Get current user information along with a list of accounts he/she has access to
|
91
140
|
|
92
141
|
```ruby
|
93
|
-
response =
|
142
|
+
response = client.users.current
|
143
|
+
response.status_code # Returns response HTTP code.
|
144
|
+
response.body # Contains hash with returned body (JSON is parsed automatically).
|
94
145
|
```
|
95
146
|
|
96
|
-
|
147
|
+
Accessing content of returned body:
|
97
148
|
|
98
149
|
```ruby
|
99
|
-
response
|
150
|
+
response.body["name"] # Return name of your company.
|
151
|
+
response.name # Alternative way of getting the name of your company.
|
100
152
|
```
|
101
153
|
|
102
|
-
|
154
|
+
Get a list of all account users:
|
103
155
|
|
104
156
|
```ruby
|
105
|
-
response =
|
157
|
+
response = client.users.all
|
106
158
|
```
|
107
159
|
|
108
|
-
|
160
|
+
### [Account Resource](https://www.fakturoid.cz/api/v3/account)
|
161
|
+
|
162
|
+
Get Fakturoid account information:
|
109
163
|
|
110
164
|
```ruby
|
111
|
-
response =
|
165
|
+
response = client.account.current
|
112
166
|
```
|
113
167
|
|
114
|
-
|
168
|
+
### [Bank Account Resource](https://www.fakturoid.cz/api/v3/bank-accounts)
|
169
|
+
|
170
|
+
Get a list of bank accounts for current account:
|
115
171
|
|
116
172
|
```ruby
|
117
|
-
response =
|
173
|
+
response = client.bank_accounts.all
|
118
174
|
```
|
119
175
|
|
120
|
-
|
176
|
+
### [Number Format Resource](https://www.fakturoid.cz/api/v3/number-formats)
|
177
|
+
|
178
|
+
Get a list of invoice number formats for current account:
|
121
179
|
|
122
180
|
```ruby
|
123
|
-
|
181
|
+
response = client.number_formats.invoices
|
124
182
|
```
|
125
183
|
|
126
|
-
|
184
|
+
### [Subject Resource](https://www.fakturoid.cz/api/v3/subjects)
|
127
185
|
|
128
|
-
|
186
|
+
Get a list of subjects:
|
129
187
|
|
130
|
-
|
188
|
+
```ruby
|
189
|
+
response = client.subjects.all(page: 2)
|
190
|
+
```
|
191
|
+
|
192
|
+
Fulltext search:
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
response = client.subjects.search(query: "Client name")
|
196
|
+
```
|
197
|
+
|
198
|
+
Get a specific subject:
|
131
199
|
|
132
200
|
```ruby
|
133
|
-
response =
|
201
|
+
response = client.subjects.find(subject_id)
|
134
202
|
```
|
135
203
|
|
136
|
-
|
204
|
+
Create a new subject:
|
137
205
|
|
138
206
|
```ruby
|
139
|
-
response =
|
207
|
+
response = client.subjects.create(name: "New client")
|
140
208
|
```
|
141
209
|
|
142
|
-
|
210
|
+
Update a subject:
|
143
211
|
|
144
212
|
```ruby
|
145
|
-
response =
|
213
|
+
response = client.subjects.update(subject_id, name: "Updated client")
|
146
214
|
```
|
147
215
|
|
148
|
-
|
216
|
+
Delete a subject:
|
149
217
|
|
150
218
|
```ruby
|
151
|
-
|
219
|
+
client.subjects.delete(subject_id)
|
220
|
+
```
|
221
|
+
|
222
|
+
### [Invoice Resource](https://www.fakturoid.cz/api/v3/invoices)
|
223
|
+
|
224
|
+
Get a list of invoices:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
response = client.invoices.all
|
228
|
+
```
|
229
|
+
|
230
|
+
Fulltext search:
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
response = client.invoices.search(query: "Client name")
|
234
|
+
response = client.invoices.search(tags: "Housing")
|
235
|
+
response = client.invoices.search(tags: ["Housing", "Rent"])
|
236
|
+
response = client.invoices.search(query: "Client name", tags: ["Housing"])
|
237
|
+
```
|
238
|
+
|
239
|
+
Get invoice details:
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
response = client.invoices.find(invoice_id)
|
243
|
+
```
|
244
|
+
|
245
|
+
Download invoice in PDF format:
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
response = client.invoices.download_pdf(invoice_id)
|
152
249
|
|
153
250
|
File.open("/path/to/file.pdf", "wb") do |f|
|
154
251
|
f.write(response.body)
|
155
252
|
end
|
156
253
|
```
|
157
254
|
|
158
|
-
|
255
|
+
Download an attachment:
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
response = client.invoices.download_attachment(invoice_id, attachment_id)
|
259
|
+
|
260
|
+
File.open("/path/to/attachment.pdf", "wb") do |f|
|
261
|
+
f.write(response.body)
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
Invoice actions (eg. lock invoice, cancel, etc., full list is in the API documentation):
|
159
266
|
|
160
267
|
```ruby
|
161
|
-
|
268
|
+
response = client.invoices.fire(invoice_id, "lock")
|
269
|
+
```
|
270
|
+
|
271
|
+
Create an invoice:
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
data = {
|
162
275
|
subject_id: 123,
|
163
276
|
lines: [
|
164
277
|
{
|
@@ -170,79 +283,222 @@ invoice = {
|
|
170
283
|
}
|
171
284
|
]
|
172
285
|
}
|
173
|
-
response =
|
286
|
+
response = client.invoices.create(data)
|
287
|
+
```
|
288
|
+
|
289
|
+
Update an invoice:
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
response = client.invoices.update(invoice_id, number: "2015-0015")
|
174
293
|
```
|
175
294
|
|
176
|
-
|
295
|
+
Delete an invoice:
|
177
296
|
|
178
297
|
```ruby
|
179
|
-
response =
|
298
|
+
response = client.invoices.delete(invoice_id)
|
180
299
|
```
|
181
300
|
|
182
|
-
|
301
|
+
### [Invoice Payment Resource](https://www.fakturoid.cz/api/v3/invoice-payments)
|
302
|
+
|
303
|
+
Create an invoice payment:
|
183
304
|
|
184
305
|
```ruby
|
185
|
-
|
306
|
+
response = client.invoice_payments.create(invoice_id, paid_on: Date.today)
|
307
|
+
response = client.invoice_payments.create(invoice_id, amount: "500")
|
308
|
+
````
|
309
|
+
|
310
|
+
Create a tax document for a payment:
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
response = client.invoice_payments.create_tax_document(invoice_id, payment_id)
|
314
|
+
tax_document_response = client.invoices.find(response.tax_document_id)
|
315
|
+
````
|
316
|
+
|
317
|
+
Delete a payment:
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
response = client.invoice_payments.delete(invoice_id, payment_id)
|
321
|
+
```
|
322
|
+
|
323
|
+
### [Invoice Message Resource](https://www.fakturoid.cz/api/v3/invoice-messages)
|
324
|
+
|
325
|
+
Send a message to the client (you can use more variables in the `message`, full list is in the API documentation):
|
326
|
+
|
327
|
+
```ruby
|
328
|
+
data = {
|
186
329
|
email: "testemail@testemail.cz",
|
187
330
|
email_copy: "some@emailcopy.cz",
|
188
331
|
subject: "I have an invoice for you",
|
189
332
|
message: "Hi,\n\nyou can find invoice no. #no# on the following page #link#\n\nHave a nice day"
|
190
333
|
}
|
191
334
|
|
192
|
-
response =
|
193
|
-
|
335
|
+
response = client.invoice_messages.create(invoice_id, data)
|
336
|
+
```
|
337
|
+
|
338
|
+
### [Expense Resource](https://www.fakturoid.cz/api/v3/expenses)
|
339
|
+
|
340
|
+
Get a list of expenses:
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
response = client.expenses.all
|
344
|
+
```
|
345
|
+
|
346
|
+
Fulltext search:
|
347
|
+
|
348
|
+
```ruby
|
349
|
+
response = client.expenses.search(query: "Supplier name")
|
350
|
+
response = client.expenses.search(tags: "Housing")
|
351
|
+
response = client.expenses.search(tags: ["Housing", "Rent"])
|
352
|
+
response = client.expenses.search(query: "Supplier name", tags: ["Housing"])
|
353
|
+
```
|
354
|
+
|
355
|
+
Get expense details:
|
356
|
+
|
357
|
+
```ruby
|
358
|
+
response = client.expenses.find(expense_id)
|
359
|
+
```
|
360
|
+
|
361
|
+
Download an attachment:
|
362
|
+
|
363
|
+
```ruby
|
364
|
+
response = client.expenses.download_attachment(expense_id, attachment_id)
|
365
|
+
|
366
|
+
File.open("/path/to/attachment.pdf", "wb") do |f|
|
367
|
+
f.write(response.body)
|
368
|
+
end
|
369
|
+
```
|
370
|
+
|
371
|
+
Expense actions (eg. lock expense etc., full list is in the API documentation):
|
372
|
+
|
373
|
+
```ruby
|
374
|
+
response = client.expenses.fire(expense_id, "lock")
|
375
|
+
```
|
376
|
+
|
377
|
+
Create an expense:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
data = {
|
381
|
+
subject_id: 123,
|
382
|
+
lines: [
|
383
|
+
{
|
384
|
+
quantity: 5,
|
385
|
+
unit_name: "kg",
|
386
|
+
name: "Sand",
|
387
|
+
unit_price: "100",
|
388
|
+
vat_rate: 21
|
389
|
+
}
|
390
|
+
]
|
391
|
+
}
|
392
|
+
response = client.expenses.create(data)
|
393
|
+
```
|
394
|
+
|
395
|
+
Update an expense:
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
response = client.expenses.update(expense_id, number: "N20240201")
|
194
399
|
```
|
195
400
|
|
196
|
-
|
401
|
+
Delete an expense:
|
197
402
|
|
198
403
|
```ruby
|
199
|
-
response =
|
404
|
+
response = client.expenses.delete(expense_id)
|
200
405
|
```
|
201
406
|
|
202
|
-
|
407
|
+
### [Expense Payment Resource](https://www.fakturoid.cz/api/v3/expense-payments)
|
408
|
+
|
409
|
+
Create an expense payment:
|
410
|
+
|
411
|
+
```ruby
|
412
|
+
response = client.expense_payments.create(expense_id, paid_on: Date.today)
|
413
|
+
response = client.expense_payments.create(expense_id, amount: "500")
|
414
|
+
````
|
415
|
+
|
416
|
+
Delete a payment:
|
203
417
|
|
204
418
|
```ruby
|
205
|
-
response =
|
419
|
+
response = client.expense_payments.delete(expense_id, payment_id)
|
206
420
|
```
|
207
421
|
|
208
|
-
|
422
|
+
### [Inbox File Resource](https://www.fakturoid.cz/api/v3/inbox-files)
|
209
423
|
|
210
|
-
|
424
|
+
Get a list of inbox files:
|
211
425
|
|
212
|
-
|
426
|
+
```ruby
|
427
|
+
response = client.inbox_files.all
|
428
|
+
```
|
213
429
|
|
430
|
+
Create an inbox file:
|
431
|
+
|
214
432
|
```ruby
|
215
|
-
|
433
|
+
require "base64"
|
434
|
+
|
435
|
+
client.inbox_files.create(
|
436
|
+
attachment: "data:application/pdf;base64,#{Base64.urlsafe_encode64(File.read("some-file.pdf"))}",
|
437
|
+
filename: "some-file.pdf", # This is optional and defaults to `attachment.{extension}`.
|
438
|
+
send_to_ocr: true # Also optional
|
439
|
+
)
|
216
440
|
```
|
217
441
|
|
218
|
-
|
442
|
+
Send a file to OCR (data extraction service):
|
219
443
|
|
220
444
|
```ruby
|
221
|
-
|
445
|
+
client.inbox_files.send_to_ocr(inbox_file_id)
|
222
446
|
```
|
223
447
|
|
224
|
-
|
448
|
+
Download a file:
|
225
449
|
|
226
450
|
```ruby
|
227
|
-
|
451
|
+
filename = client.inbox_files.find(inbox_file_id).filename
|
452
|
+
response = client.inbox_files.download(inbox_file_id)
|
453
|
+
|
454
|
+
File.open("/path/to/file.pdf", "wb") do |f|
|
455
|
+
f.write(response.body)
|
456
|
+
end
|
228
457
|
```
|
229
458
|
|
230
|
-
|
459
|
+
Delete a file:
|
231
460
|
|
232
461
|
```ruby
|
233
|
-
response =
|
462
|
+
response = client.inbox_files.delete(inbox_file_id)
|
234
463
|
```
|
235
464
|
|
236
|
-
|
465
|
+
### [InventoryItem Resource](https://www.fakturoid.cz/api/v3/inventory-items)
|
466
|
+
|
467
|
+
Get a list of inventory items:
|
237
468
|
|
238
469
|
```ruby
|
239
|
-
response =
|
470
|
+
response = client.inventory_items.all
|
471
|
+
response = client.inventory_items.all(sku: "SKU1234") # Filter by SKU code
|
240
472
|
```
|
241
473
|
|
242
|
-
|
474
|
+
Get a list of archived inventory items:
|
243
475
|
|
244
476
|
```ruby
|
245
|
-
|
477
|
+
response = client.inventory_items.archived
|
478
|
+
```
|
479
|
+
|
480
|
+
Get a list of inventory items that are running low on quantity:
|
481
|
+
|
482
|
+
```ruby
|
483
|
+
response = client.inventory_items.low_quantity
|
484
|
+
```
|
485
|
+
|
486
|
+
Search inventory items (searches in `name`, `article_number` and `sku`):
|
487
|
+
|
488
|
+
```ruby
|
489
|
+
response = client.inventory_items.search(query: "Item name")
|
490
|
+
```
|
491
|
+
|
492
|
+
Get a single inventory item:
|
493
|
+
|
494
|
+
```ruby
|
495
|
+
response = client.inventory_items.find(inventory_item_id)
|
496
|
+
```
|
497
|
+
|
498
|
+
Create an inventory item:
|
499
|
+
|
500
|
+
```ruby
|
501
|
+
data = {
|
246
502
|
name: "Item name",
|
247
503
|
sku: "SKU1234",
|
248
504
|
track_quantity: true,
|
@@ -250,57 +506,57 @@ inventory_item = {
|
|
250
506
|
native_purchase_price: 500,
|
251
507
|
native_retail_price: 1000
|
252
508
|
}
|
253
|
-
response =
|
509
|
+
response = client.inventory_items.create(data)
|
254
510
|
```
|
255
511
|
|
256
|
-
|
512
|
+
Update an inventory item:
|
257
513
|
|
258
514
|
```ruby
|
259
|
-
response =
|
515
|
+
response = client.inventory_items.update(inventory_item_id, name: "Another name")
|
260
516
|
```
|
261
517
|
|
262
|
-
|
518
|
+
Delete an inventory item:
|
263
519
|
|
264
520
|
```ruby
|
265
|
-
response =
|
521
|
+
response = client.inventory_items.delete(inventory_item_id)
|
266
522
|
```
|
267
523
|
|
268
|
-
|
524
|
+
Archive an inventory item:
|
269
525
|
|
270
526
|
```ruby
|
271
|
-
response =
|
527
|
+
response = client.inventory_items.archive(inventory_item_id)
|
272
528
|
```
|
273
529
|
|
274
|
-
|
530
|
+
Unarchive an inventory item:
|
275
531
|
|
276
532
|
```ruby
|
277
|
-
response =
|
533
|
+
response = client.inventory_items.unarchive(inventory_item_id)
|
278
534
|
```
|
279
535
|
|
280
|
-
### InventoryMove
|
536
|
+
### [InventoryMove Resource](https://www.fakturoid.cz/api/v3/inventory-moves)
|
281
537
|
|
282
|
-
|
538
|
+
Get a list of inventory moves across all inventory items:
|
283
539
|
|
284
540
|
```ruby
|
285
|
-
response =
|
541
|
+
response = client.inventory_moves.all
|
286
542
|
```
|
287
543
|
|
288
|
-
|
544
|
+
Get a list of inventory moves for a single inventory item:
|
289
545
|
|
290
546
|
```ruby
|
291
|
-
response =
|
547
|
+
response = client.inventory_moves.all(inventory_item_id: inventory_item_id)
|
292
548
|
```
|
293
549
|
|
294
|
-
|
550
|
+
Get a single inventory move:
|
295
551
|
|
296
552
|
```ruby
|
297
|
-
response =
|
553
|
+
response = client.inventory_moves.find(inventory_item_id, inventory_move_id)
|
298
554
|
```
|
299
555
|
|
300
|
-
|
556
|
+
Create a stock-in inventory move:
|
301
557
|
|
302
558
|
```ruby
|
303
|
-
response =
|
559
|
+
response = client.inventory_moves.create(
|
304
560
|
inventory_item_id,
|
305
561
|
direction: "in",
|
306
562
|
moved_on: Date.today,
|
@@ -311,10 +567,10 @@ response = Fakturoid::Client::InventoryMoves.create(
|
|
311
567
|
)
|
312
568
|
```
|
313
569
|
|
314
|
-
|
570
|
+
Create a stock-out inventory move:
|
315
571
|
|
316
572
|
```ruby
|
317
|
-
response =
|
573
|
+
response = client.inventory_moves.create(
|
318
574
|
inventory_item_id,
|
319
575
|
direction: "out",
|
320
576
|
moved_on: Date.today,
|
@@ -325,29 +581,181 @@ response = Fakturoid::Client::InventoryMoves.create(
|
|
325
581
|
)
|
326
582
|
```
|
327
583
|
|
328
|
-
|
584
|
+
Update an inventory move:
|
329
585
|
|
330
586
|
```ruby
|
331
|
-
|
587
|
+
data = {
|
332
588
|
private_note: "Text"
|
333
589
|
# Plus other fields if necessary
|
334
590
|
}
|
335
|
-
response =
|
591
|
+
response = client.inventory_moves.update(inventory_item_id, inventory_move_id, data)
|
592
|
+
```
|
593
|
+
|
594
|
+
Delete an inventory move:
|
595
|
+
|
596
|
+
```ruby
|
597
|
+
response = client.inventory_moves.delete(inventory_item_id, inventory_move_id)
|
598
|
+
```
|
599
|
+
|
600
|
+
### [Generator Resource](https://www.fakturoid.cz/api/v3/generators)
|
601
|
+
|
602
|
+
Get a list of generators:
|
603
|
+
|
604
|
+
```ruby
|
605
|
+
response = client.generators.all
|
606
|
+
```
|
607
|
+
|
608
|
+
Get generator details:
|
609
|
+
|
610
|
+
```ruby
|
611
|
+
response = client.generators.find(generator_id)
|
612
|
+
```
|
613
|
+
|
614
|
+
Create a generator:
|
615
|
+
|
616
|
+
```ruby
|
617
|
+
data = {
|
618
|
+
name: "Workshop",
|
619
|
+
subject_id: 123,
|
620
|
+
lines: [
|
621
|
+
{
|
622
|
+
quantity: 5,
|
623
|
+
unit_name: "kg",
|
624
|
+
name: "Sand",
|
625
|
+
unit_price: "100",
|
626
|
+
vat_rate: 21
|
627
|
+
}
|
628
|
+
]
|
629
|
+
}
|
630
|
+
response = client.generators.create(data)
|
631
|
+
```
|
632
|
+
|
633
|
+
Update an generator:
|
634
|
+
|
635
|
+
```ruby
|
636
|
+
response = client.generators.update(generator_id, name: "Another name")
|
637
|
+
```
|
638
|
+
|
639
|
+
Delete an generator:
|
640
|
+
|
641
|
+
```ruby
|
642
|
+
response = client.generators.delete(generator_id)
|
643
|
+
```
|
644
|
+
|
645
|
+
### [RecurringGenerator Resource](https://www.fakturoid.cz/api/v3/recurring-generators)
|
646
|
+
|
647
|
+
Get a list of recurring generators:
|
648
|
+
|
649
|
+
```ruby
|
650
|
+
response = client.recurring_generators.all
|
651
|
+
```
|
652
|
+
|
653
|
+
Get recurring generator details:
|
654
|
+
|
655
|
+
```ruby
|
656
|
+
response = client.recurring_generators.find(recurring_generator_id)
|
657
|
+
```
|
658
|
+
|
659
|
+
Create a recurring generator:
|
660
|
+
|
661
|
+
```ruby
|
662
|
+
data = {
|
663
|
+
name: "Workshop",
|
664
|
+
subject_id: subject_id,
|
665
|
+
start_date: Date.today,
|
666
|
+
months_period: 1,
|
667
|
+
lines: [
|
668
|
+
{
|
669
|
+
quantity: 5,
|
670
|
+
unit_name: "kg",
|
671
|
+
name: "Sand",
|
672
|
+
unit_price: "100",
|
673
|
+
vat_rate: 21
|
674
|
+
}
|
675
|
+
]
|
676
|
+
}
|
677
|
+
response = client.recurring_generators.create(data)
|
678
|
+
```
|
679
|
+
|
680
|
+
Update a recurring generator:
|
681
|
+
|
682
|
+
```ruby
|
683
|
+
response = client.recurring_generators.update(recurring_generator_id, name: "Another name")
|
684
|
+
```
|
685
|
+
|
686
|
+
Delete a recurring generator:
|
687
|
+
|
688
|
+
```ruby
|
689
|
+
response = client.recurring_generators.delete(recurring_generator_id)
|
690
|
+
```
|
691
|
+
### [Event Resource](https://www.fakturoid.cz/api/v3/events)
|
692
|
+
|
693
|
+
Get a list of all events:
|
694
|
+
|
695
|
+
```ruby
|
696
|
+
response = client.events.all
|
697
|
+
````
|
698
|
+
|
699
|
+
Get a list of document-paid events:
|
700
|
+
|
701
|
+
```ruby
|
702
|
+
response = client.events.paid
|
703
|
+
````
|
704
|
+
|
705
|
+
### [Todo Resource](https://www.fakturoid.cz/api/v3/todos)
|
706
|
+
|
707
|
+
Get a list of all todos:
|
708
|
+
|
709
|
+
```ruby
|
710
|
+
response = client.todos.all
|
711
|
+
````
|
712
|
+
|
713
|
+
Toggle a todo completion:
|
714
|
+
|
715
|
+
```ruby
|
716
|
+
response = client.todos.toggle_completion(todo_id)
|
717
|
+
```
|
718
|
+
|
719
|
+
### [Webhook Resource](https://www.fakturoid.cz/api/v3/webhooks)
|
720
|
+
|
721
|
+
Get a list of all webhooks:
|
722
|
+
|
723
|
+
```ruby
|
724
|
+
response = client.webhooks.all
|
725
|
+
```
|
726
|
+
|
727
|
+
Get a single webhook:
|
728
|
+
|
729
|
+
```ruby
|
730
|
+
response = client.webhooks.find(webhook_id)
|
731
|
+
```
|
732
|
+
|
733
|
+
Create a webhook:
|
734
|
+
|
735
|
+
```ruby
|
736
|
+
response = client.webhooks.create(webhook_url: "https://example.com/webhook", events: %w[invoice_created])
|
737
|
+
```
|
738
|
+
|
739
|
+
Update a webhook:
|
740
|
+
|
741
|
+
```ruby
|
742
|
+
response = client.webhooks.update(webhook_id, webhook_url: "https://example.com/webhook")
|
336
743
|
```
|
337
744
|
|
338
|
-
|
745
|
+
Delete a webhook:
|
339
746
|
|
340
747
|
```ruby
|
341
|
-
response =
|
748
|
+
response = client.webhooks.delete(webhook_id)
|
342
749
|
```
|
343
750
|
|
344
|
-
## Handling
|
751
|
+
## Handling Errors
|
345
752
|
|
346
|
-
The Fakturoid gem raises exceptions if
|
753
|
+
The Fakturoid gem raises exceptions if server responds with an error.
|
754
|
+
All exceptions except `ConfigurationError` contain following attributes:
|
347
755
|
|
348
|
-
|
349
|
-
|
350
|
-
|
756
|
+
- `message`: Error description
|
757
|
+
- `response_code`: HTTP code of error (only number)
|
758
|
+
- `response_body`: Response body parsed as a hash
|
351
759
|
|
352
760
|
<table>
|
353
761
|
<thead>
|
@@ -357,49 +765,36 @@ The Fakturoid gem raises exceptions if error response is returned from the serve
|
|
357
765
|
</thead>
|
358
766
|
<tbody>
|
359
767
|
<tr>
|
360
|
-
<td>
|
361
|
-
</tr>
|
362
|
-
<tr>
|
363
|
-
<td>UserAgentError</td><td>400 Bad Request</td><td>Missing `user_agent` configuration</td>
|
364
|
-
</tr>
|
365
|
-
<tr>
|
366
|
-
<td>PaginationError</td><td>400 Bad Request</td><td>Page with given number does not exist</td>
|
367
|
-
</tr>
|
368
|
-
<tr>
|
369
|
-
<td>AuthenticationError</td><td>401 Unauthorized</td><td>Wrong authentication `email` or `api_key` configuration</td>
|
370
|
-
</tr>
|
371
|
-
<tr>
|
372
|
-
<td>BlockedAccountError</td><td>402 Payment Required</td><td>Fakturoid account is blocked</td>
|
768
|
+
<td>ConfigurationError</td><td>N/A</td><td>Important configuration is missing.</td>
|
373
769
|
</tr>
|
374
770
|
<tr>
|
375
|
-
<td>
|
771
|
+
<td>OauthError</td><td>400 Bad Request</td><td>OAuth request fails.</td>
|
376
772
|
</tr>
|
377
773
|
<tr>
|
378
|
-
<td>
|
774
|
+
<td>AuthenticationError</td><td>401 Unauthorized</td><td>Authentication fails due to client credentials error or access token expired.</td>
|
379
775
|
</tr>
|
380
776
|
<tr>
|
381
|
-
<td>
|
777
|
+
<td>ClientError</td><td>4XX</td><td>User-sent data are invalid.</td>
|
382
778
|
</tr>
|
383
779
|
<tr>
|
384
|
-
<td>
|
385
|
-
</tr>
|
386
|
-
<tr>
|
387
|
-
<td>DestroySubjectError</td><td>403 Forbidden</td><td>Subject has invoices or expenses and cannot be deleted</td>
|
388
|
-
</tr>
|
389
|
-
<tr>
|
390
|
-
<td>SubjectLimitError</td><td>403 Forbidden</td><td>Subject quota reached for adding more subjects upgrade to higher plan</td>
|
391
|
-
</tr>
|
392
|
-
<tr>
|
393
|
-
<td>GeneratorLimitError</td><td>403 Forbidden</td><td>Generator quota reached for adding more recurring generators upgrade to higher plan</td>
|
394
|
-
</tr>
|
395
|
-
<tr>
|
396
|
-
<td>UnsupportedFeatureError</td><td>403 Forbidden</td><td>Feature is not supported in your plan to use this feature upgrade to higher plan</td>
|
397
|
-
</tr>
|
398
|
-
<tr>
|
399
|
-
<td>ClientError</td><td>4XX</td><td>Server returns response code which is not specified above</td>
|
400
|
-
</tr>
|
401
|
-
<tr>
|
402
|
-
<td>ServerError</td><td>5XX</td><td>Server returns response code which is not specified above</td>
|
780
|
+
<td>ServerError</td><td>5XX</td><td>An exception happened while processing a request.</td>
|
403
781
|
</tr>
|
404
782
|
</tbody>
|
405
783
|
</table>
|
784
|
+
|
785
|
+
## Contributing
|
786
|
+
|
787
|
+
- Make a pull request with requested changes.
|
788
|
+
- Make sure the pull request is as small as possible. If you encounter something that should be changed but is unrelated,
|
789
|
+
please make a separate pull request for that.
|
790
|
+
- Do not change the version number inside the pull request – this will be done after it is merged.
|
791
|
+
|
792
|
+
## Development
|
793
|
+
|
794
|
+
```sh
|
795
|
+
git clone <repo-url>
|
796
|
+
cd fakturoid-ruby
|
797
|
+
bundle
|
798
|
+
bundle exec rake # Run tests
|
799
|
+
bundle exec rake build # Test the package building process
|
800
|
+
```
|