fortnox-api 1.0.0.rc2 → 1.0.0.rc3
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/CHANGELOG.md +36 -6
- data/README.md +5 -3
- data/lib/fortnox/mappers/document_row.rb +2 -1
- data/lib/fortnox/resources/article.rb +1 -1
- data/lib/fortnox/resources/customer.rb +3 -3
- data/lib/fortnox/resources/document.rb +3 -3
- data/lib/fortnox/resources/invoice.rb +3 -3
- data/lib/fortnox/version.rb +1 -1
- data/lib/fortnox.rb +39 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2297de9b35ce0c8d7f3f0e3b84f0a44a443062d257f843876657a6d26a4da160
|
|
4
|
+
data.tar.gz: b328a297acaa35278c2b943b10bc2dc04b7e8dfbf2dd65642346f35c572bb950
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a73b124f68428feaaccbfea406a025bb24995b7dce7e88959dee7aca21ab449e4c92cbae11808b33c50cf8f8e498d6039399157cdcc5e68c3bcb6cfce5a35b30
|
|
7
|
+
data.tar.gz: aa5b472af7edc87d4f808581ae99545e1b99f33d7319890843d442d9f2c7d1afe7db6fb04d509a5524d5b7f405337e0b6043d8155be1e5b3ebf2b8e83d3e75e9
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,29 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
6
6
|
and this project adheres to
|
|
7
7
|
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
8
8
|
|
|
9
|
+
## [1.0.0.rc3] - 2026-05-08
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `Fortnox::RequestError#message` now includes the API's
|
|
14
|
+
`ErrorInformation.Message` and code from the response body when present,
|
|
15
|
+
normalising Fortnox's inconsistent key casing (PascalCase vs lowercase)
|
|
16
|
+
across endpoints. Previously the message was only `"Request failed: <status>"`,
|
|
17
|
+
hiding the cause from logs and uncaught backtraces.
|
|
18
|
+
- `Article#commodity_code`, `Customer#phone`, `Invoice#accounting_method`,
|
|
19
|
+
`Invoice#invoice_period_reference`, `Invoice#invoice_reference`,
|
|
20
|
+
`Document#time_basis_reference`, `Document#total_to_pay`, and
|
|
21
|
+
`Document#warehouse_ready` are now flagged read-only to match the Fortnox
|
|
22
|
+
API. Values set on these attributes are silently excluded from save
|
|
23
|
+
requests; previously they were sent and rejected by the API.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- `Order` and `Invoice` rows now serialise the VAT field as `VAT` instead of
|
|
28
|
+
`Vat`. Saving rows with a `vat` value previously failed with Fortnox
|
|
29
|
+
rejecting the request as `"Felaktigt fältnamn"`. This bug was introduced in the 1.0.0.rc1,
|
|
30
|
+
it did not exist in 0.x.
|
|
31
|
+
|
|
9
32
|
## [1.0.0.rc2] - 2026-05-05
|
|
10
33
|
|
|
11
34
|
### Added
|
|
@@ -22,16 +45,22 @@ and this project adheres to
|
|
|
22
45
|
prescriptive default that didn't reflect the actual resource set. Other
|
|
23
46
|
Fortnox scopes (`salary`, `bookkeeping`, etc.) can still be entered
|
|
24
47
|
manually.
|
|
25
|
-
- `TermsOfPayment.code`
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
API documentation. The rest-easy rewrite for rc1 briefly lost the
|
|
30
|
-
required flag.
|
|
48
|
+
- `TermsOfPayment.code` now has a 25-character limit, matching Fortnox
|
|
49
|
+
API documentation.
|
|
50
|
+
- `Unit.code` now has a 20-character limit, matching Fortnox API
|
|
51
|
+
documentation.
|
|
31
52
|
- `Unit.description` is now `Sized::String[100]` and required, matching
|
|
32
53
|
Fortnox API documentation. In 0.x and rc1 this was nullable client-side,
|
|
33
54
|
but the Fortnox API rejected unset descriptions anyway.
|
|
34
55
|
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- `TermsOfPayment.code` is required again, matching Fortnox API
|
|
59
|
+
documentation. The rest-easy rewrite for rc1 briefly lost the required
|
|
60
|
+
flag.
|
|
61
|
+
- `Unit.code` is required again, matching Fortnox API documentation. The
|
|
62
|
+
rest-easy rewrite for rc1 briefly lost the required flag.
|
|
63
|
+
|
|
35
64
|
## [1.0.0.rc1] - 2026-05-04
|
|
36
65
|
|
|
37
66
|
Version 1.0 is a complete rewrite of the gem and is **not** a drop-in
|
|
@@ -139,5 +168,6 @@ for the full list of breaking changes.
|
|
|
139
168
|
For changes prior to the 1.0 rewrite, see the
|
|
140
169
|
[0.x changelog](https://github.com/accodeing/fortnox-api/blob/v0.9.2/CHANGELOG.md).
|
|
141
170
|
|
|
171
|
+
[1.0.0.rc3]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc2...v1.0.0.rc3
|
|
142
172
|
[1.0.0.rc2]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc1...v1.0.0.rc2
|
|
143
173
|
[1.0.0.rc1]: https://github.com/accodeing/fortnox-api/releases/tag/v1.0.0.rc1
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Adding more resources is quick and easy, see the
|
|
|
16
16
|
## Status
|
|
17
17
|
|
|
18
18
|
Version 1.0 is a complete rewrite, currently in release candidate
|
|
19
|
-
(`1.0.0.
|
|
19
|
+
(`1.0.0.rc3`). It is built on
|
|
20
20
|
[rest-easy](https://github.com/accodeing/rest-easy), replacing the old
|
|
21
21
|
HTTParty + Data Mapper architecture with a single resource class per entity.
|
|
22
22
|
Authorization uses the Fortnox client credentials flow.
|
|
@@ -68,8 +68,10 @@ The gem raises the following exceptions:
|
|
|
68
68
|
|
|
69
69
|
- `Fortnox::Error` — base class for everything below. Rescue this to catch
|
|
70
70
|
any error raised by the gem.
|
|
71
|
-
- `Fortnox::RequestError` — 4xx/5xx responses from the Fortnox API.
|
|
72
|
-
the
|
|
71
|
+
- `Fortnox::RequestError` — 4xx/5xx responses from the Fortnox API. The
|
|
72
|
+
exception message includes the API's `ErrorInformation.Message` and code
|
|
73
|
+
when present (Fortnox is inconsistent about the key casing — the gem
|
|
74
|
+
normalises both). The full response is on `.response`.
|
|
73
75
|
- `Fortnox::AttributeError` — base for attribute validation failures.
|
|
74
76
|
- `Fortnox::ConstraintError` — an attribute value violates a type
|
|
75
77
|
constraint (max size, format, etc.). Carries `.attribute_name` and
|
|
@@ -155,6 +155,6 @@ module Fortnox
|
|
|
155
155
|
attr :default_stock_location, Coercible::String.optional
|
|
156
156
|
|
|
157
157
|
# CommodityCode Commodity code of the article.
|
|
158
|
-
attr :commodity_code, Coercible::String.optional
|
|
158
|
+
attr :commodity_code, Coercible::String.optional, :read_only
|
|
159
159
|
end
|
|
160
160
|
end
|
|
@@ -131,6 +131,9 @@ module Fortnox
|
|
|
131
131
|
# Our reference
|
|
132
132
|
attr :our_reference, Sized::String[50]
|
|
133
133
|
|
|
134
|
+
# Phone number of the customer. Only present in collection responses.
|
|
135
|
+
attr :phone, Coercible::String.optional, :read_only
|
|
136
|
+
|
|
134
137
|
# First phone number of the customer
|
|
135
138
|
attr :phone1, Sized::String[1024]
|
|
136
139
|
|
|
@@ -191,9 +194,6 @@ module Fortnox
|
|
|
191
194
|
# Active If the customer is active.
|
|
192
195
|
attr :active, Bool.optional, Boolean
|
|
193
196
|
|
|
194
|
-
# Phone number of the customer. Only present in collection responses.
|
|
195
|
-
attr :phone, Coercible::String.optional
|
|
196
|
-
|
|
197
197
|
# External reference
|
|
198
198
|
attr :external_reference, Sized::String[1024]
|
|
199
199
|
|
|
@@ -191,12 +191,12 @@ module Fortnox
|
|
|
191
191
|
attr :outbound_date, Date.optional, Mappers::Date
|
|
192
192
|
|
|
193
193
|
# TimeBasisReference Reference to time basis.
|
|
194
|
-
attr :time_basis_reference, Coercible::Integer.optional
|
|
194
|
+
attr :time_basis_reference, Coercible::Integer.optional, :read_only
|
|
195
195
|
|
|
196
196
|
# TotalToPay Total amount to pay.
|
|
197
|
-
attr :total_to_pay, Coercible::Float.optional
|
|
197
|
+
attr :total_to_pay, Coercible::Float.optional, :read_only
|
|
198
198
|
|
|
199
199
|
# WarehouseReady If the document is warehouse ready.
|
|
200
|
-
attr :warehouse_ready, Bool.optional, Boolean
|
|
200
|
+
attr :warehouse_ready, Bool.optional, :read_only, Boolean
|
|
201
201
|
end
|
|
202
202
|
end
|
|
@@ -12,7 +12,7 @@ module Fortnox
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# AccountingMethod Accounting Method.
|
|
15
|
-
attr :accounting_method, AccountingMethods
|
|
15
|
+
attr :accounting_method, AccountingMethods, :read_only
|
|
16
16
|
|
|
17
17
|
# Balance Balance of the invoice.
|
|
18
18
|
attr :balance, Coercible::Float.optional, :read_only
|
|
@@ -51,10 +51,10 @@ module Fortnox
|
|
|
51
51
|
attr :invoice_period_end, Date.optional, :read_only, Mappers::Date
|
|
52
52
|
|
|
53
53
|
# InvoicePeriodReference Reference to the invoice period.
|
|
54
|
-
attr :invoice_period_reference, Coercible::String.optional
|
|
54
|
+
attr :invoice_period_reference, Coercible::String.optional, :read_only
|
|
55
55
|
|
|
56
56
|
# InvoiceReference Reference to another invoice.
|
|
57
|
-
attr :invoice_reference, Coercible::String.optional
|
|
57
|
+
attr :invoice_reference, Coercible::String.optional, :read_only
|
|
58
58
|
|
|
59
59
|
# InvoiceRows Separate object
|
|
60
60
|
attr :invoice_rows, Strict::Array.of(Structs::InvoiceRow), Mappers::StructArray.for(Mappers::InvoiceRow)
|
data/lib/fortnox/version.rb
CHANGED
data/lib/fortnox.rb
CHANGED
|
@@ -23,11 +23,49 @@ module Fortnox
|
|
|
23
23
|
def initialize(arg = nil)
|
|
24
24
|
if arg.respond_to?(:status)
|
|
25
25
|
@response = arg
|
|
26
|
-
super("Request failed: #{arg.status}")
|
|
26
|
+
super("Request failed: #{arg.status}#{format_body(arg.body)}")
|
|
27
27
|
else
|
|
28
28
|
super
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
|
+
|
|
32
|
+
BODY_FALLBACK_LIMIT = 500
|
|
33
|
+
private_constant :BODY_FALLBACK_LIMIT
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def format_body(body)
|
|
38
|
+
return '' if body.nil? || body.empty?
|
|
39
|
+
|
|
40
|
+
" - #{error_details(body) || truncate(body.to_s)}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Fortnox have at least in the past sometimes returned HTML responses on error,
|
|
44
|
+
# for instance 503 Service Temporarily Unavailable.
|
|
45
|
+
# In that case, the body might be long and useful for debugging,
|
|
46
|
+
# so let's truncate it to a reasonable length if we end up here.
|
|
47
|
+
def truncate(string)
|
|
48
|
+
string.length > BODY_FALLBACK_LIMIT ? "#{string[0, BODY_FALLBACK_LIMIT]}…" : string
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def error_details(body)
|
|
52
|
+
info = error_information(body)
|
|
53
|
+
message = info && info['message']
|
|
54
|
+
return nil unless message
|
|
55
|
+
|
|
56
|
+
code = info['code']
|
|
57
|
+
code ? "#{message} (#{code})" : message
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def error_information(body)
|
|
61
|
+
parsed = body.is_a?(String) ? JSON.parse(body) : body
|
|
62
|
+
info = parsed['ErrorInformation'] if parsed.is_a?(Hash)
|
|
63
|
+
# Fortnox responds with inconsistently-cased error keys (see tests),
|
|
64
|
+
# so let's normalise to lowercase before reading.
|
|
65
|
+
info.is_a?(Hash) ? info.transform_keys(&:downcase) : nil
|
|
66
|
+
rescue JSON::ParserError
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
31
69
|
end
|
|
32
70
|
|
|
33
71
|
class AttributeError < Error; end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fortnox-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.0.
|
|
4
|
+
version: 1.0.0.rc3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jonas Schubert Erlandsson
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2026-05-
|
|
14
|
+
date: 2026-05-08 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: countries
|