fortnox-api 1.0.0.rc7 → 1.0.0.rc9
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 +30 -1
- data/README.md +11 -1
- data/bin/fortnox-setup +9 -3
- data/lib/fortnox/resources/customer.rb +23 -0
- data/lib/fortnox/structs/default_delivery_types.rb +4 -4
- data/lib/fortnox/types.rb +4 -0
- data/lib/fortnox/version.rb +1 -1
- data/lib/fortnox.rb +8 -0
- 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: a20aeb0e4dd1618609c445e649bc8b1d5014febdc7eafcb733d4477a054dca60
|
|
4
|
+
data.tar.gz: '02592cebf00ea6190f2d0d863a54441346e973e06e0f65fd4e436cda63c57587'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d65bbab5d39d6428068de1132c2e5d0251acfd3c4e70fe120d37fbb0680d6e82f861935106e6386c4b3b2951f8a513b19b821009459a6e5c4a69f38a9368d50f
|
|
7
|
+
data.tar.gz: 95858ca85e8694c9d699ec7dd054f5c93e7a1fce3ca078d8bb690ee61f0e691a44cff23f4c3a5633459659234560815a766391ca2d12dce3b1f804f54abb486f
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,33 @@ and this project adheres to
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.0.0.rc9] - 2026-05-20
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- `Fortnox::ALLOWED_CHARACTERS_REGEXP` constant, exposing the character
|
|
16
|
+
set Fortnox accepts in text fields. Sourced from the official Fortnox
|
|
17
|
+
docs. Useful for pre-validating strings before sending them to the API.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `Customer#default_delivery_types.invoice` now accepts `'ELECTRONICINVOICE'`
|
|
22
|
+
when returned by Fortnox. The value is read-only — attempting to set it from
|
|
23
|
+
consumer code raises `Fortnox::ConstraintError` at save time,
|
|
24
|
+
rather than letting Fortnox reject the request.
|
|
25
|
+
Unchanged values round-trip through `save` as before.
|
|
26
|
+
|
|
27
|
+
## [1.0.0.rc8] - 2026-05-19
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `fortnox-setup` now prints the authorization URL and asks before
|
|
32
|
+
opening a browser when a non-localhost redirect URI is used, defaulting
|
|
33
|
+
to not opening it. Previously it always opened the URL locally, so the
|
|
34
|
+
browser immediately followed the redirect and the URL was lost — making
|
|
35
|
+
it impossible to hand off to whoever should log in (e.g. a customer).
|
|
36
|
+
The local-server flow is unchanged.
|
|
37
|
+
|
|
11
38
|
## [1.0.0.rc7] - 2026-05-19
|
|
12
39
|
|
|
13
40
|
### Changed
|
|
@@ -217,7 +244,9 @@ for the full list of breaking changes.
|
|
|
217
244
|
For changes prior to the 1.0 rewrite, see the
|
|
218
245
|
[0.x changelog](https://github.com/accodeing/fortnox-api/blob/v0.9.2/CHANGELOG.md).
|
|
219
246
|
|
|
220
|
-
[Unreleased]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.
|
|
247
|
+
[Unreleased]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc9...HEAD
|
|
248
|
+
[1.0.0.rc9]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc8...v1.0.0.rc9
|
|
249
|
+
[1.0.0.rc8]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc7...v1.0.0.rc8
|
|
221
250
|
[1.0.0.rc7]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc6...v1.0.0.rc7
|
|
222
251
|
[1.0.0.rc6]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc5...v1.0.0.rc6
|
|
223
252
|
[1.0.0.rc5]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc4...v1.0.0.rc5
|
data/README.md
CHANGED
|
@@ -18,7 +18,7 @@ Adding more resources is quick and easy — see the
|
|
|
18
18
|
## Status
|
|
19
19
|
|
|
20
20
|
Version 1.0 is a complete rewrite, currently in release candidate
|
|
21
|
-
(`1.0.0.
|
|
21
|
+
(`1.0.0.rc8`). It is built on
|
|
22
22
|
[rest-easy](https://github.com/accodeing/rest-easy), replacing the old
|
|
23
23
|
HTTParty + Data Mapper architecture with a single resource class per entity.
|
|
24
24
|
Authorization uses the Fortnox client credentials flow.
|
|
@@ -64,6 +64,16 @@ sending it to the API, which saves you API calls and time debugging. You can
|
|
|
64
64
|
still get errors from the server; our implementation is not perfect. Also,
|
|
65
65
|
Fortnox sometimes requires a specific combination of attributes.
|
|
66
66
|
|
|
67
|
+
#### Allowed characters
|
|
68
|
+
|
|
69
|
+
`Fortnox::ALLOWED_CHARACTERS_REGEXP` exposes the character set Fortnox
|
|
70
|
+
accepts in text fields, sourced from the [official Fortnox docs][formats].
|
|
71
|
+
The gem itself does not apply this regex to attribute values — it is
|
|
72
|
+
provided so consumers can pre-validate or sanitize strings before
|
|
73
|
+
sending them to the API.
|
|
74
|
+
|
|
75
|
+
[formats]: https://www.fortnox.se/developer/guides-and-good-to-know/formats-and-encoding
|
|
76
|
+
|
|
67
77
|
#### Exceptions
|
|
68
78
|
|
|
69
79
|
The gem raises the following exceptions:
|
data/bin/fortnox-setup
CHANGED
|
@@ -154,15 +154,21 @@ auth_params = URI.encode_www_form(
|
|
|
154
154
|
authorize_url = "#{OAUTH_ENDPOINT}/auth?#{auth_params}"
|
|
155
155
|
|
|
156
156
|
puts
|
|
157
|
-
puts 'Opening browser for Fortnox authorization...'
|
|
158
|
-
|
|
159
|
-
open_browser(authorize_url)
|
|
160
157
|
|
|
161
158
|
if use_local_server
|
|
159
|
+
puts 'Opening browser for Fortnox authorization...'
|
|
160
|
+
open_browser(authorize_url)
|
|
162
161
|
puts
|
|
163
162
|
puts 'Waiting for Fortnox to redirect back...'
|
|
164
163
|
authorization_code = get_auth_code_from_server(LOCAL_PORT, nonce)
|
|
165
164
|
else
|
|
165
|
+
puts 'Authorization URL. Open it to log in, or send it to whoever should'
|
|
166
|
+
puts 'log in to the Fortnox account being connected:'
|
|
167
|
+
puts
|
|
168
|
+
puts " #{authorize_url}"
|
|
169
|
+
puts
|
|
170
|
+
open_here = prompt('Open it in your browser now?', default: 'n')
|
|
171
|
+
open_browser(authorize_url) if open_here.downcase.start_with?('y')
|
|
166
172
|
authorization_code = auth_code_manually
|
|
167
173
|
end
|
|
168
174
|
|
|
@@ -11,6 +11,10 @@ module Fortnox
|
|
|
11
11
|
scope 'customer'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
+
before_serialise do |_attrs|
|
|
15
|
+
validate_electronic_invoice_delivery_type!(default_delivery_types&.invoice)
|
|
16
|
+
end
|
|
17
|
+
|
|
14
18
|
# Direct URL to the record.
|
|
15
19
|
attr :url <=> '@url', Coercible::String.optional, :read_only
|
|
16
20
|
|
|
@@ -205,5 +209,24 @@ module Fortnox
|
|
|
205
209
|
|
|
206
210
|
# WWW Website URL
|
|
207
211
|
attr :www <=> 'WWW', Sized::String[128]
|
|
212
|
+
|
|
213
|
+
private
|
|
214
|
+
|
|
215
|
+
# ELECTRONICINVOICE is only possible to set in the Fortnox UI.
|
|
216
|
+
# Raise if a consumer tries to set it from this gem.
|
|
217
|
+
def validate_electronic_invoice_delivery_type!(type)
|
|
218
|
+
return unless type == DefaultInvoiceDeliveryTypeValues['ELECTRONICINVOICE']
|
|
219
|
+
|
|
220
|
+
set_by_consumer = meta.new? || __changes__.key?(:default_delivery_types)
|
|
221
|
+
|
|
222
|
+
return unless set_by_consumer
|
|
223
|
+
|
|
224
|
+
raise Fortnox::ConstraintError.new(
|
|
225
|
+
:default_delivery_types,
|
|
226
|
+
'ELECTRONICINVOICE',
|
|
227
|
+
"Customer#default_delivery_types.invoice cannot be changed to 'ELECTRONICINVOICE' " \
|
|
228
|
+
'via the API, you can only do that change from within Fortnox.'
|
|
229
|
+
)
|
|
230
|
+
end
|
|
208
231
|
end
|
|
209
232
|
end
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
module Fortnox
|
|
4
4
|
module Structs
|
|
5
5
|
class DefaultDeliveryTypes < Fortnox::Struct
|
|
6
|
-
# Default delivery type for invoices.
|
|
7
|
-
attribute? :invoice, Types::
|
|
6
|
+
# Default delivery type for invoices.
|
|
7
|
+
attribute? :invoice, Types::DefaultInvoiceDeliveryTypeValues
|
|
8
8
|
|
|
9
|
-
# Default delivery type for orders.
|
|
9
|
+
# Default delivery type for orders.
|
|
10
10
|
attribute? :order, Types::DefaultDeliveryTypeValues
|
|
11
11
|
|
|
12
|
-
# Default delivery type for offers.
|
|
12
|
+
# Default delivery type for offers.
|
|
13
13
|
attribute? :offer, Types::DefaultDeliveryTypeValues
|
|
14
14
|
end
|
|
15
15
|
end
|
data/lib/fortnox/types.rb
CHANGED
|
@@ -66,6 +66,10 @@ module Fortnox
|
|
|
66
66
|
'PRINT', 'EMAIL', 'PRINTSERVICE'
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
+
DefaultInvoiceDeliveryTypeValues = Types::Strict::String.enum(
|
|
70
|
+
'PRINT', 'EMAIL', 'PRINTSERVICE', 'ELECTRONICINVOICE'
|
|
71
|
+
)
|
|
72
|
+
|
|
69
73
|
AccountingMethods = Types::Strict::String.enum(
|
|
70
74
|
'', 'ACCRUAL', 'CASH'
|
|
71
75
|
)
|
data/lib/fortnox/version.rb
CHANGED
data/lib/fortnox.rb
CHANGED
|
@@ -93,6 +93,14 @@ module Fortnox
|
|
|
93
93
|
|
|
94
94
|
OAUTH_TOKEN_URL = 'https://apps.fortnox.se/oauth-v1/token'
|
|
95
95
|
|
|
96
|
+
# Character set allowed in Fortnox text fields, per the official Fortnox docs.
|
|
97
|
+
# Useful for pre-validating strings before sending them to the API.
|
|
98
|
+
# See: https://www.fortnox.se/developer/guides-and-good-to-know/formats-and-encoding
|
|
99
|
+
# (The docs spell Unicode codepoints as \x{NNNN}; Ruby's regex parser uses
|
|
100
|
+
# \u{NNNN} for the same thing, so the three codepoints below are translated.)
|
|
101
|
+
ALLOWED_CHARACTERS_REGEXP =
|
|
102
|
+
%r{\A[\p{L}’\\\u{0308}\u{030a}a-zåäöéáœæøüA-ZÅÄÖÉÁÜŒÆØ0-9 –:.`´,;\^¤#%§£$€¢¥©™°&/()=+\-*_!?²³®½@\u{00a0}\n\r]*\z}
|
|
103
|
+
|
|
96
104
|
class << self
|
|
97
105
|
def access_token=(token)
|
|
98
106
|
Thread.current[Auth::ThreadLocal::THREAD_LOCAL_KEY] = token
|
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.rc9
|
|
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-20 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: base64
|