fortnox-api 1.0.0.rc12 → 1.0.0.rc13
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 +53 -1
- data/lib/fortnox/mappers/country_code.rb +5 -2
- data/lib/fortnox/resource.rb +33 -14
- data/lib/fortnox/resources/article.rb +16 -16
- data/lib/fortnox/resources/customer.rb +12 -12
- data/lib/fortnox/resources/document.rb +29 -29
- data/lib/fortnox/resources/invoice.rb +11 -11
- data/lib/fortnox/resources/label.rb +1 -1
- data/lib/fortnox/resources/order.rb +4 -4
- data/lib/fortnox/resources/project.rb +1 -1
- data/lib/fortnox/resources/terms_of_payment.rb +1 -1
- data/lib/fortnox/resources/unit.rb +1 -1
- data/lib/fortnox/structs/document_row.rb +7 -7
- data/lib/fortnox/structs/edi_information.rb +6 -6
- data/lib/fortnox/structs/invoice_row.rb +2 -2
- data/lib/fortnox/types.rb +37 -7
- data/lib/fortnox/version.rb +1 -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: 695db94ae3937bdcc80a1737e65b730cc58dd6784b79eedf6296490b716ab31a
|
|
4
|
+
data.tar.gz: 3a25be836c8d7251578d71b40364c122673176c89b878a7a8ed21d68c0eb2377
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz: '
|
|
6
|
+
metadata.gz: c8fb345adff538fbb9e0d1db6c0d653bebbfa35014ecb0b78e7ee5940c9f8f6f77eab563a2378f2d0827822a44a56fe0bf0fffc06e4c961e84850ae07b83adf9
|
|
7
|
+
data.tar.gz: '05914af9563412c342711d69418462bbd47335ea09aa46d13bf581906fd80a81fea2d1b997dc5a27f61c98b54f705637f502c4b44c3d66fcc78aea8c0368dd5c'
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,57 @@ and this project adheres to
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [1.0.0.rc13] - 2026-08-04
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- String attributes now normalise `''` to `nil` at the type level. This
|
|
16
|
+
is the mechanism behind the reset fix below: Fortnox silently ignores
|
|
17
|
+
empty strings in update payloads — updating an attribute to `''` kept
|
|
18
|
+
the original value — and a field can only be cleared with an explicit
|
|
19
|
+
`null`. Normalising in the type also changes the read side: unset
|
|
20
|
+
string attributes read as `nil` in the model, never `''`. Fortnox
|
|
21
|
+
spells "unset" as `""` or `null` depending on endpoint and record
|
|
22
|
+
history, so the model value was previously unpredictable. Consumers
|
|
23
|
+
comparing against `''` must switch to `nil` checks (or call `.to_s`
|
|
24
|
+
if they prefer empty strings). On create, an attribute set to `''`
|
|
25
|
+
is now omitted from the POST body entirely (new records strip
|
|
26
|
+
`nil`s), leaving the field to Fortnox's default — previously `""`
|
|
27
|
+
was sent, which Fortnox ignores, with the same end result.
|
|
28
|
+
Enum-typed attributes whose value set
|
|
29
|
+
includes `''` (`payment_way`, `accounting_method`, `invoice_type`,
|
|
30
|
+
`tax_reduction_type`, `delivery_state`) are exempt: there `''` is a
|
|
31
|
+
real Fortnox value, not an unset spelling. For required string attributes
|
|
32
|
+
(`Customer#name`, `Article#description`, `Unit#code`/`#description`,
|
|
33
|
+
`TermsOfPayment#code`) this means updating to `''` now raises
|
|
34
|
+
`Fortnox::MissingAttributeError` before any request is made —
|
|
35
|
+
previously the empty string was sent and silently ignored by Fortnox
|
|
36
|
+
(clearing a required field is invalid: Fortnox rejects `null` for
|
|
37
|
+
them with a 400 and ignores `""`).
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Resetting a string attribute to `''` on update now clears the value in
|
|
42
|
+
Fortnox. Previously the empty string was silently ignored by Fortnox
|
|
43
|
+
and the old value was left intact (reported for `Customer#comments`).
|
|
44
|
+
Since `''` now coerces to `nil` (see above), both `update(attr: '')`
|
|
45
|
+
and `update(attr: nil)` reach Fortnox as `null`, which clears. This
|
|
46
|
+
includes the country attributes on documents (`country_code`,
|
|
47
|
+
`delivery_country`), whose mapper previously turned `nil` back into
|
|
48
|
+
`""` on the wire, so countries could never be cleared at all.
|
|
49
|
+
- Numeric attributes no longer raise `Fortnox::ConstraintError` when
|
|
50
|
+
Fortnox returns `""` for an unset value — blank coerces to `nil`,
|
|
51
|
+
extending the 1.0.0.rc10 `Types::AccountNumber` fix to all integer
|
|
52
|
+
and float attributes (e.g. `Customer#invoice_discount`,
|
|
53
|
+
`Invoice#balance`). Like that bug, this was introduced in 1.0.0.rc1
|
|
54
|
+
and did not exist in 0.x, which coerced `""` to `0`/`0.0`.
|
|
55
|
+
- `#update`, `#serialise` (and `#to_api`, which goes through it) and
|
|
56
|
+
`.new` now raise Fortnox-namespaced errors. A coercion failure like
|
|
57
|
+
`customer.update(email: 'not-an-email')` previously leaked
|
|
58
|
+
`RestEasy::ConstraintError`, which `rescue Fortnox::ConstraintError`
|
|
59
|
+
blocks don't catch — error translation only covered `save`, `parse`,
|
|
60
|
+
`find`, `stub` and the other class-level paths.
|
|
61
|
+
|
|
11
62
|
## [1.0.0.rc12] - 2026-06-26
|
|
12
63
|
|
|
13
64
|
### Fixed
|
|
@@ -281,7 +332,8 @@ for the full list of breaking changes.
|
|
|
281
332
|
For changes prior to the 1.0 rewrite, see the
|
|
282
333
|
[0.x changelog](https://github.com/accodeing/fortnox-api/blob/v0.9.2/CHANGELOG.md).
|
|
283
334
|
|
|
284
|
-
[Unreleased]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.
|
|
335
|
+
[Unreleased]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc13...HEAD
|
|
336
|
+
[1.0.0.rc13]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc12...v1.0.0.rc13
|
|
285
337
|
[1.0.0.rc12]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc11...v1.0.0.rc12
|
|
286
338
|
[1.0.0.rc11]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc10...v1.0.0.rc11
|
|
287
339
|
[1.0.0.rc10]: https://github.com/accodeing/fortnox-api/compare/v1.0.0.rc9...v1.0.0.rc10
|
|
@@ -7,8 +7,11 @@ module Fortnox
|
|
|
7
7
|
module CountryCode
|
|
8
8
|
ISO3166.configure { |config| config.locales = [:en, :sv] }
|
|
9
9
|
|
|
10
|
+
# Blank maps to nil in both directions, mirroring the string types:
|
|
11
|
+
# Fortnox spells "unset" country as "" on reads, and on updates only
|
|
12
|
+
# an explicit null clears the field — "" is silently ignored.
|
|
10
13
|
def self.parse(country)
|
|
11
|
-
return
|
|
14
|
+
return nil if country.nil? || country == ''
|
|
12
15
|
|
|
13
16
|
# Fortnox only supports Swedish translation of Sweden
|
|
14
17
|
return 'SE' if country =~ /^s(e$|we|ve)/i
|
|
@@ -23,7 +26,7 @@ module Fortnox
|
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def self.serialise(country_code)
|
|
26
|
-
return
|
|
29
|
+
return nil if country_code.nil? || country_code == ''
|
|
27
30
|
|
|
28
31
|
return 'Sverige' if country_code == 'SE'
|
|
29
32
|
|
data/lib/fortnox/resource.rb
CHANGED
|
@@ -26,6 +26,27 @@ module Fortnox
|
|
|
26
26
|
|
|
27
27
|
after_serialise { |data| default_after_serialise(data) }
|
|
28
28
|
|
|
29
|
+
# Translate rest-easy errors at the gem boundary so callers only see
|
|
30
|
+
# Fortnox-namespaced exceptions.
|
|
31
|
+
module ErrorTranslation
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def with_translated_errors
|
|
35
|
+
yield
|
|
36
|
+
rescue RestEasy::ConstraintError => e
|
|
37
|
+
raise Fortnox::ConstraintError.new(e.attribute_name, e.value, e.message)
|
|
38
|
+
rescue RestEasy::MissingAttributeError => e
|
|
39
|
+
raise Fortnox::MissingAttributeError, e.attribute_name
|
|
40
|
+
rescue RestEasy::AttributeError => e
|
|
41
|
+
raise Fortnox::AttributeError, e.message
|
|
42
|
+
rescue RestEasy::RequestError => e
|
|
43
|
+
raise Fortnox::RequestError, e.response || e.message
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
include ErrorTranslation # instance-level methods
|
|
48
|
+
extend ErrorTranslation # class-level methods
|
|
49
|
+
|
|
29
50
|
class << self
|
|
30
51
|
attr_reader :registered_resources
|
|
31
52
|
|
|
@@ -42,6 +63,10 @@ module Fortnox
|
|
|
42
63
|
end
|
|
43
64
|
end
|
|
44
65
|
|
|
66
|
+
def new(...)
|
|
67
|
+
with_translated_errors { super }
|
|
68
|
+
end
|
|
69
|
+
|
|
45
70
|
def stub(**model_data)
|
|
46
71
|
with_translated_errors { super }
|
|
47
72
|
end
|
|
@@ -94,20 +119,6 @@ module Fortnox
|
|
|
94
119
|
|
|
95
120
|
private
|
|
96
121
|
|
|
97
|
-
# Translate rest-easy errors at the gem boundary so callers only see
|
|
98
|
-
# Fortnox-namespaced exceptions.
|
|
99
|
-
def with_translated_errors
|
|
100
|
-
yield
|
|
101
|
-
rescue RestEasy::ConstraintError => e
|
|
102
|
-
raise Fortnox::ConstraintError.new(e.attribute_name, e.value, e.message)
|
|
103
|
-
rescue RestEasy::MissingAttributeError => e
|
|
104
|
-
raise Fortnox::MissingAttributeError, e.attribute_name
|
|
105
|
-
rescue RestEasy::AttributeError => e
|
|
106
|
-
raise Fortnox::AttributeError, e.message
|
|
107
|
-
rescue RestEasy::RequestError => e
|
|
108
|
-
raise Fortnox::RequestError, e.response || e.message
|
|
109
|
-
end
|
|
110
|
-
|
|
111
122
|
def extract_pagination(data)
|
|
112
123
|
return {} unless data.is_a?(Hash) && data.key?('MetaInformation')
|
|
113
124
|
|
|
@@ -120,6 +131,14 @@ module Fortnox
|
|
|
120
131
|
end
|
|
121
132
|
end
|
|
122
133
|
|
|
134
|
+
def update(...)
|
|
135
|
+
with_translated_errors { super }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def serialise(...)
|
|
139
|
+
with_translated_errors { super }
|
|
140
|
+
end
|
|
141
|
+
|
|
123
142
|
private
|
|
124
143
|
|
|
125
144
|
# Shared serialisation tail used by the base after_serialise hook. Exposed
|
|
@@ -12,7 +12,7 @@ module Fortnox
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# @url Direct URL to the record.
|
|
15
|
-
attr :url <=> '@url',
|
|
15
|
+
attr :url <=> '@url', UnsizedString, :read_only
|
|
16
16
|
|
|
17
17
|
# True If the article is active
|
|
18
18
|
attr :active, Bool.optional, Boolean
|
|
@@ -34,7 +34,7 @@ module Fortnox
|
|
|
34
34
|
attr :description, Sized::String[200], :required
|
|
35
35
|
|
|
36
36
|
# DisposableQuantity Disposable quantity of the article.
|
|
37
|
-
attr :disposable_quantity,
|
|
37
|
+
attr :disposable_quantity, UnsizedFloat, :read_only
|
|
38
38
|
|
|
39
39
|
# EAN EAN bar code
|
|
40
40
|
attr :ean <=> 'EAN', Sized::String[30]
|
|
@@ -80,14 +80,14 @@ module Fortnox
|
|
|
80
80
|
attr :quantity_in_stock, Sized::Float[-100_000_000_000_000.0, 99_999_999_999_999.9]
|
|
81
81
|
|
|
82
82
|
# ReservedQuantity Reserved quantity of the article
|
|
83
|
-
attr :reserved_quantity,
|
|
83
|
+
attr :reserved_quantity, UnsizedFloat, :read_only
|
|
84
84
|
|
|
85
85
|
# SalesAccount Account number for the sales account in Sweden.
|
|
86
86
|
# The number must be of an existing account.
|
|
87
87
|
attr :sales_account, Types::AccountNumber
|
|
88
88
|
|
|
89
89
|
# SalesPrice Price of article for its default price list
|
|
90
|
-
attr :sales_price,
|
|
90
|
+
attr :sales_price, UnsizedFloat, :read_only
|
|
91
91
|
|
|
92
92
|
# StockGoods If the article is stock goods
|
|
93
93
|
attr :stock_goods, Bool.optional, Boolean
|
|
@@ -96,27 +96,27 @@ module Fortnox
|
|
|
96
96
|
attr :stock_place, Sized::String[100]
|
|
97
97
|
|
|
98
98
|
# StockValue Value in stock of the article
|
|
99
|
-
attr :stock_value,
|
|
99
|
+
attr :stock_value, UnsizedFloat, :read_only
|
|
100
100
|
|
|
101
101
|
# StockWarning When to start warning for low quantity in stock
|
|
102
102
|
attr :stock_warning, Sized::Float[0.0, 99_999_999_999_999.9]
|
|
103
103
|
|
|
104
104
|
# SupplierName Name of the supplier
|
|
105
|
-
attr :supplier_name,
|
|
105
|
+
attr :supplier_name, UnsizedString, :read_only
|
|
106
106
|
|
|
107
107
|
# SupplierNumber Supplier number for the article.
|
|
108
108
|
# The number must be of an existing supplier.
|
|
109
|
-
attr :supplier_number,
|
|
109
|
+
attr :supplier_number, UnsizedString
|
|
110
110
|
|
|
111
111
|
# Type The type of the article
|
|
112
112
|
attr :type, ArticleTypes
|
|
113
113
|
|
|
114
114
|
# Unit Unit code for the article.
|
|
115
115
|
# The code must be of an existing unit.
|
|
116
|
-
attr :unit,
|
|
116
|
+
attr :unit, UnsizedString
|
|
117
117
|
|
|
118
118
|
# VAT VAT percent, this is predefined by the VAT for the sales account
|
|
119
|
-
attr :vat <=> 'VAT',
|
|
119
|
+
attr :vat <=> 'VAT', UnsizedFloat
|
|
120
120
|
|
|
121
121
|
# WebshopArticle If the article is a webshop article
|
|
122
122
|
attr :webshop_article, Bool.optional, Boolean
|
|
@@ -131,7 +131,7 @@ module Fortnox
|
|
|
131
131
|
attr :expired, Bool.optional, Boolean
|
|
132
132
|
|
|
133
133
|
# CostCalculationMethod Cost calculation method used for the article.
|
|
134
|
-
attr :cost_calculation_method,
|
|
134
|
+
attr :cost_calculation_method, UnsizedString
|
|
135
135
|
|
|
136
136
|
# StockAccount Account number for stock.
|
|
137
137
|
attr :stock_account, Types::AccountNumber
|
|
@@ -140,21 +140,21 @@ module Fortnox
|
|
|
140
140
|
attr :stock_change_account, Types::AccountNumber
|
|
141
141
|
|
|
142
142
|
# DirectCost Direct cost of the article.
|
|
143
|
-
attr :direct_cost,
|
|
143
|
+
attr :direct_cost, UnsizedFloat
|
|
144
144
|
|
|
145
145
|
# FreightCost Freight cost of the article.
|
|
146
|
-
attr :freight_cost,
|
|
146
|
+
attr :freight_cost, UnsizedFloat
|
|
147
147
|
|
|
148
148
|
# OtherCost Other cost of the article.
|
|
149
|
-
attr :other_cost,
|
|
149
|
+
attr :other_cost, UnsizedFloat
|
|
150
150
|
|
|
151
151
|
# DefaultStockPoint Default stock point for the article.
|
|
152
|
-
attr :default_stock_point,
|
|
152
|
+
attr :default_stock_point, UnsizedString
|
|
153
153
|
|
|
154
154
|
# DefaultStockLocation Default stock location for the article.
|
|
155
|
-
attr :default_stock_location,
|
|
155
|
+
attr :default_stock_location, UnsizedString
|
|
156
156
|
|
|
157
157
|
# CommodityCode Commodity code of the article.
|
|
158
|
-
attr :commodity_code,
|
|
158
|
+
attr :commodity_code, UnsizedString, :read_only
|
|
159
159
|
end
|
|
160
160
|
end
|
|
@@ -25,7 +25,7 @@ module Fortnox
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# Direct URL to the record.
|
|
28
|
-
attr :url <=> '@url',
|
|
28
|
+
attr :url <=> '@url', UnsizedString, :read_only
|
|
29
29
|
|
|
30
30
|
# First address of the customer
|
|
31
31
|
attr :address1, Sized::String[1024]
|
|
@@ -37,7 +37,7 @@ module Fortnox
|
|
|
37
37
|
attr :city, Sized::String[1024]
|
|
38
38
|
|
|
39
39
|
# Country of the customer
|
|
40
|
-
attr :country,
|
|
40
|
+
attr :country, UnsizedString, :read_only
|
|
41
41
|
|
|
42
42
|
# Comments
|
|
43
43
|
attr :comments, Sized::String[1024]
|
|
@@ -46,7 +46,7 @@ module Fortnox
|
|
|
46
46
|
attr :currency, Currencies
|
|
47
47
|
|
|
48
48
|
# Cost center of the customer
|
|
49
|
-
attr :cost_center,
|
|
49
|
+
attr :cost_center, UnsizedString
|
|
50
50
|
|
|
51
51
|
# Country code of the customer
|
|
52
52
|
attr :country_code, Sized::String[2]
|
|
@@ -70,7 +70,7 @@ module Fortnox
|
|
|
70
70
|
attr :delivery_city, Sized::String[1024]
|
|
71
71
|
|
|
72
72
|
# Delivery country of the customer
|
|
73
|
-
attr :delivery_country,
|
|
73
|
+
attr :delivery_country, UnsizedString, :read_only
|
|
74
74
|
|
|
75
75
|
# Delivery country code of the customer
|
|
76
76
|
attr :delivery_country_code, Sized::String[2]
|
|
@@ -145,7 +145,7 @@ module Fortnox
|
|
|
145
145
|
attr :our_reference, Sized::String[50]
|
|
146
146
|
|
|
147
147
|
# Phone number of the customer. Only present in collection responses.
|
|
148
|
-
attr :phone,
|
|
148
|
+
attr :phone, UnsizedString, :read_only
|
|
149
149
|
|
|
150
150
|
# First phone number of the customer
|
|
151
151
|
attr :phone1, Sized::String[1024]
|
|
@@ -154,10 +154,10 @@ module Fortnox
|
|
|
154
154
|
attr :phone2, Sized::String[1024]
|
|
155
155
|
|
|
156
156
|
# Price list of the customer
|
|
157
|
-
attr :price_list,
|
|
157
|
+
attr :price_list, UnsizedString
|
|
158
158
|
|
|
159
159
|
# Project of the customer
|
|
160
|
-
attr :project,
|
|
160
|
+
attr :project, UnsizedString
|
|
161
161
|
|
|
162
162
|
# Sales account of the customer
|
|
163
163
|
attr :sales_account, Types::AccountNumber
|
|
@@ -166,16 +166,16 @@ module Fortnox
|
|
|
166
166
|
attr :show_price_vat_included <=> 'ShowPriceVATIncluded', Bool.optional, Boolean
|
|
167
167
|
|
|
168
168
|
# Terms of delivery code
|
|
169
|
-
attr :terms_of_delivery,
|
|
169
|
+
attr :terms_of_delivery, UnsizedString
|
|
170
170
|
|
|
171
171
|
# Terms of payment code
|
|
172
|
-
attr :terms_of_payment,
|
|
172
|
+
attr :terms_of_payment, UnsizedString
|
|
173
173
|
|
|
174
174
|
# Customer type
|
|
175
175
|
attr :type, CustomerTypes
|
|
176
176
|
|
|
177
177
|
# VAT number of the customer
|
|
178
|
-
attr :vat_number <=> 'VATNumber',
|
|
178
|
+
attr :vat_number <=> 'VATNumber', UnsizedString
|
|
179
179
|
|
|
180
180
|
# VAT type of the customer
|
|
181
181
|
attr :vat_type <=> 'VATType', VATTypes
|
|
@@ -187,7 +187,7 @@ module Fortnox
|
|
|
187
187
|
attr :visiting_city, Sized::String[128]
|
|
188
188
|
|
|
189
189
|
# Visit country of the customer
|
|
190
|
-
attr :visiting_country,
|
|
190
|
+
attr :visiting_country, UnsizedString, :read_only
|
|
191
191
|
|
|
192
192
|
# Visiting country code
|
|
193
193
|
attr :visiting_country_code, Sized::String[2]
|
|
@@ -196,7 +196,7 @@ module Fortnox
|
|
|
196
196
|
attr :visiting_zip_code, Sized::String[10]
|
|
197
197
|
|
|
198
198
|
# Way of delivery code
|
|
199
|
-
attr :way_of_delivery,
|
|
199
|
+
attr :way_of_delivery, UnsizedString
|
|
200
200
|
|
|
201
201
|
# Your reference
|
|
202
202
|
attr :your_reference, Sized::String[50]
|
|
@@ -8,16 +8,16 @@ module Fortnox
|
|
|
8
8
|
using RestEasy::Refinements
|
|
9
9
|
|
|
10
10
|
# Url Direct url to the record.
|
|
11
|
-
attr :url <=> '@url',
|
|
11
|
+
attr :url <=> '@url', UnsizedString, :read_only
|
|
12
12
|
|
|
13
13
|
# @urlTaxReductionList Direct URL to the tax reduction list.
|
|
14
|
-
attr :tax_reduction_list_url <=> '@urlTaxReductionList',
|
|
14
|
+
attr :tax_reduction_list_url <=> '@urlTaxReductionList', UnsizedString, :read_only
|
|
15
15
|
|
|
16
16
|
# AdministrationFee The document administration fee.
|
|
17
|
-
attr :administration_fee,
|
|
17
|
+
attr :administration_fee, UnsizedFloat
|
|
18
18
|
|
|
19
19
|
# AdministrationFeeVAT VAT of the document administration fee.
|
|
20
|
-
attr :administration_fee_vat <=> 'AdministrationFeeVAT',
|
|
20
|
+
attr :administration_fee_vat <=> 'AdministrationFeeVAT', UnsizedFloat, :read_only
|
|
21
21
|
|
|
22
22
|
# Address1 Document address 1.
|
|
23
23
|
attr :address1, Sized::String[1024]
|
|
@@ -26,7 +26,7 @@ module Fortnox
|
|
|
26
26
|
attr :address2, Sized::String[1024]
|
|
27
27
|
|
|
28
28
|
# BasisTaxReduction Basis of tax reduction.
|
|
29
|
-
attr :basis_tax_reduction,
|
|
29
|
+
attr :basis_tax_reduction, UnsizedFloat, :read_only
|
|
30
30
|
|
|
31
31
|
# Cancelled If the document is cancelled.
|
|
32
32
|
attr :cancelled, Bool.optional, :read_only, Boolean
|
|
@@ -38,25 +38,25 @@ module Fortnox
|
|
|
38
38
|
attr :comments, Sized::String[1024]
|
|
39
39
|
|
|
40
40
|
# ContributionPercent Document contribution in percent.
|
|
41
|
-
attr :contribution_percent,
|
|
41
|
+
attr :contribution_percent, UnsizedFloat, :read_only
|
|
42
42
|
|
|
43
43
|
# ContributionValue Document contribution in amount.
|
|
44
|
-
attr :contribution_value,
|
|
44
|
+
attr :contribution_value, UnsizedFloat, :read_only
|
|
45
45
|
|
|
46
46
|
# Country Country for the document address.
|
|
47
47
|
attr :country_code <=> 'Country', Sized::String[2], Mappers::CountryCode
|
|
48
48
|
|
|
49
49
|
# CostCenter Code of the cost center.
|
|
50
|
-
attr :cost_center,
|
|
50
|
+
attr :cost_center, UnsizedString
|
|
51
51
|
|
|
52
52
|
# Currency Code of the currency.
|
|
53
53
|
attr :currency, Currencies
|
|
54
54
|
|
|
55
55
|
# CurrencyRate Currency rate used for the document
|
|
56
|
-
attr :currency_rate,
|
|
56
|
+
attr :currency_rate, UnsizedFloat
|
|
57
57
|
|
|
58
58
|
# CurrencyUnit Currency unit used for the document
|
|
59
|
-
attr :currency_unit,
|
|
59
|
+
attr :currency_unit, UnsizedFloat
|
|
60
60
|
|
|
61
61
|
# CustomerName Name of the customer
|
|
62
62
|
attr :customer_name, Sized::String[1024]
|
|
@@ -86,7 +86,7 @@ module Fortnox
|
|
|
86
86
|
attr :delivery_zip_code, Sized::String[1024]
|
|
87
87
|
|
|
88
88
|
# DocumentNumber The document number.
|
|
89
|
-
key :document_number,
|
|
89
|
+
key :document_number, UnsizedInteger
|
|
90
90
|
|
|
91
91
|
# EmailInformation Separate EmailInformation object
|
|
92
92
|
attr :email_information, Structs::EmailInformation, Mappers::EmailInformation
|
|
@@ -101,10 +101,10 @@ module Fortnox
|
|
|
101
101
|
attr :freight, Sized::Float[0.0, 99_999_999_999.9]
|
|
102
102
|
|
|
103
103
|
# FreightVAT VAT of the freight cost.
|
|
104
|
-
attr :freight_vat <=> 'FreightVAT',
|
|
104
|
+
attr :freight_vat <=> 'FreightVAT', UnsizedFloat, :read_only
|
|
105
105
|
|
|
106
106
|
# Gross Gross value of the document
|
|
107
|
-
attr :gross,
|
|
107
|
+
attr :gross, UnsizedFloat, :read_only
|
|
108
108
|
|
|
109
109
|
# HouseWork If there is any row of the document marked "housework".
|
|
110
110
|
attr :housework <=> 'HouseWork', Bool.optional, :read_only, Boolean
|
|
@@ -113,16 +113,16 @@ module Fortnox
|
|
|
113
113
|
attr :labels, Strict::Array.of(Types.Instance(Label)), Mappers::LabelReferences
|
|
114
114
|
|
|
115
115
|
# Net Net amount
|
|
116
|
-
attr :net,
|
|
116
|
+
attr :net, UnsizedFloat, :read_only
|
|
117
117
|
|
|
118
118
|
# NotCompleted If the document is set as not completed.
|
|
119
119
|
attr :not_completed, Bool.optional, Boolean
|
|
120
120
|
|
|
121
121
|
# OfferReference Reference to the offer, if one exists.
|
|
122
|
-
attr :offer_reference,
|
|
122
|
+
attr :offer_reference, UnsizedInteger, :read_only
|
|
123
123
|
|
|
124
124
|
# OrganisationNumber Organisation number of the customer for the document.
|
|
125
|
-
attr :organisation_number,
|
|
125
|
+
attr :organisation_number, UnsizedString, :read_only
|
|
126
126
|
|
|
127
127
|
# OurReference Our reference
|
|
128
128
|
attr :our_reference, Sized::String[50]
|
|
@@ -134,46 +134,46 @@ module Fortnox
|
|
|
134
134
|
attr :phone2, Sized::String[1024]
|
|
135
135
|
|
|
136
136
|
# PriceList Code of the price list.
|
|
137
|
-
attr :price_list,
|
|
137
|
+
attr :price_list, UnsizedString
|
|
138
138
|
|
|
139
139
|
# PrintTemplate Print template of the document.
|
|
140
|
-
attr :print_template,
|
|
140
|
+
attr :print_template, UnsizedString
|
|
141
141
|
|
|
142
142
|
# Project Code of the project.
|
|
143
|
-
attr :project,
|
|
143
|
+
attr :project, UnsizedString
|
|
144
144
|
|
|
145
145
|
# Remarks Remarks of the document
|
|
146
146
|
attr :remarks, Sized::String[1024]
|
|
147
147
|
|
|
148
148
|
# RoundOff Round off amount for the document.
|
|
149
|
-
attr :round_off,
|
|
149
|
+
attr :round_off, UnsizedFloat, :read_only
|
|
150
150
|
|
|
151
151
|
# Sent If the document is printed or sent in any way.
|
|
152
152
|
attr :sent, Bool.optional, :read_only, Boolean
|
|
153
153
|
|
|
154
154
|
# TaxReduction The amount of tax reduction.
|
|
155
|
-
attr :tax_reduction,
|
|
155
|
+
attr :tax_reduction, UnsizedInteger, :read_only
|
|
156
156
|
|
|
157
157
|
# TaxReductionType Type of tax reduction.
|
|
158
158
|
attr :tax_reduction_type, TaxReductionTypes
|
|
159
159
|
|
|
160
160
|
# TermsOfDelivery Code of the terms of delivery.
|
|
161
|
-
attr :terms_of_delivery,
|
|
161
|
+
attr :terms_of_delivery, UnsizedString
|
|
162
162
|
|
|
163
163
|
# TermsOfPayment Code of the terms of payment.
|
|
164
|
-
attr :terms_of_payment,
|
|
164
|
+
attr :terms_of_payment, UnsizedString
|
|
165
165
|
|
|
166
166
|
# Total The total amount of the document.
|
|
167
|
-
attr :total,
|
|
167
|
+
attr :total, UnsizedFloat, :read_only
|
|
168
168
|
|
|
169
169
|
# TotalVAT The total VAT amount of the document.
|
|
170
|
-
attr :total_vat <=> 'TotalVAT',
|
|
170
|
+
attr :total_vat <=> 'TotalVAT', UnsizedFloat, :read_only
|
|
171
171
|
|
|
172
172
|
# VATIncluded If the price of the document is including VAT.
|
|
173
173
|
attr :vat_included <=> 'VATIncluded', Bool.optional, Boolean
|
|
174
174
|
|
|
175
175
|
# WayOfDelivery Code of the way of delivery.
|
|
176
|
-
attr :way_of_delivery,
|
|
176
|
+
attr :way_of_delivery, UnsizedString
|
|
177
177
|
|
|
178
178
|
# YourOrderNumber Your order number
|
|
179
179
|
attr :your_order_number, Sized::String[75]
|
|
@@ -185,16 +185,16 @@ module Fortnox
|
|
|
185
185
|
attr :zip_code, Sized::String[1024]
|
|
186
186
|
|
|
187
187
|
# Language Language code.
|
|
188
|
-
attr :language,
|
|
188
|
+
attr :language, UnsizedString
|
|
189
189
|
|
|
190
190
|
# OutboundDate Date of outbound delivery.
|
|
191
191
|
attr :outbound_date, Date.optional, Mappers::Date
|
|
192
192
|
|
|
193
193
|
# TimeBasisReference Reference to time basis.
|
|
194
|
-
attr :time_basis_reference,
|
|
194
|
+
attr :time_basis_reference, UnsizedInteger, :read_only
|
|
195
195
|
|
|
196
196
|
# TotalToPay Total amount to pay.
|
|
197
|
-
attr :total_to_pay,
|
|
197
|
+
attr :total_to_pay, UnsizedFloat, :read_only
|
|
198
198
|
|
|
199
199
|
# WarehouseReady If the document is warehouse ready.
|
|
200
200
|
attr :warehouse_ready, Bool.optional, :read_only, Boolean
|
|
@@ -15,7 +15,7 @@ module Fortnox
|
|
|
15
15
|
attr :accounting_method, AccountingMethods, :read_only
|
|
16
16
|
|
|
17
17
|
# Balance Balance of the invoice.
|
|
18
|
-
attr :balance,
|
|
18
|
+
attr :balance, UnsizedFloat, :read_only
|
|
19
19
|
|
|
20
20
|
# Booked If the invoice is bookkept.
|
|
21
21
|
attr :booked, Bool.optional, :read_only, Boolean
|
|
@@ -24,10 +24,10 @@ module Fortnox
|
|
|
24
24
|
attr :credit, Bool.optional, :read_only, Boolean
|
|
25
25
|
|
|
26
26
|
# CreditInvoiceReference Reference to the credit invoice, if one exists.
|
|
27
|
-
attr :credit_invoice_reference,
|
|
27
|
+
attr :credit_invoice_reference, UnsizedInteger
|
|
28
28
|
|
|
29
29
|
# ContractReference Reference to the contract, if one exists.
|
|
30
|
-
attr :contract_reference,
|
|
30
|
+
attr :contract_reference, UnsizedInteger, :read_only
|
|
31
31
|
|
|
32
32
|
# DueDate Due date of the invoice.
|
|
33
33
|
attr :due_date, Date.optional, Mappers::Date
|
|
@@ -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,
|
|
54
|
+
attr :invoice_period_reference, UnsizedString, :read_only
|
|
55
55
|
|
|
56
56
|
# InvoiceReference Reference to another invoice.
|
|
57
|
-
attr :invoice_reference,
|
|
57
|
+
attr :invoice_reference, UnsizedString, :read_only
|
|
58
58
|
|
|
59
59
|
# InvoiceRows Separate object
|
|
60
60
|
attr :invoice_rows, Strict::Array.of(Structs::InvoiceRow), Mappers::StructArray.for(Mappers::InvoiceRow)
|
|
@@ -69,24 +69,24 @@ module Fortnox
|
|
|
69
69
|
attr :nox_finans, Bool.optional, :read_only, Boolean
|
|
70
70
|
|
|
71
71
|
# OCR OCR number of the invoice.
|
|
72
|
-
attr :ocr <=> 'OCR',
|
|
72
|
+
attr :ocr <=> 'OCR', UnsizedString
|
|
73
73
|
|
|
74
74
|
# OrderReference Reference to the order, if one exists.
|
|
75
|
-
attr :order_reference,
|
|
75
|
+
attr :order_reference, UnsizedInteger, :read_only
|
|
76
76
|
|
|
77
77
|
# PaymentWay Payment way of the invoice.
|
|
78
78
|
attr :payment_way, PaymentWays
|
|
79
79
|
|
|
80
80
|
# Reminders Number of reminders sent to the customer.
|
|
81
|
-
attr :reminders,
|
|
81
|
+
attr :reminders, UnsizedInteger, :read_only
|
|
82
82
|
|
|
83
83
|
# VoucherNumber Voucher number for the invoice.
|
|
84
|
-
attr :voucher_number,
|
|
84
|
+
attr :voucher_number, UnsizedInteger, :read_only
|
|
85
85
|
|
|
86
86
|
# VoucherSeries Voucher series for the invoice.
|
|
87
|
-
attr :voucher_series,
|
|
87
|
+
attr :voucher_series, UnsizedString, :read_only
|
|
88
88
|
|
|
89
89
|
# VoucherYear Voucher year for the invoice.
|
|
90
|
-
attr :voucher_year,
|
|
90
|
+
attr :voucher_year, UnsizedInteger, :read_only
|
|
91
91
|
end
|
|
92
92
|
end
|
|
@@ -15,7 +15,7 @@ module Fortnox
|
|
|
15
15
|
attr :copy_remarks, Bool.optional, Boolean
|
|
16
16
|
|
|
17
17
|
# InvoiceReference Reference if an invoice is created from order
|
|
18
|
-
attr :invoice_reference,
|
|
18
|
+
attr :invoice_reference, UnsizedInteger, :read_only
|
|
19
19
|
|
|
20
20
|
# OrderDate Date of order
|
|
21
21
|
attr :order_date, Date.optional, Mappers::Date
|
|
@@ -27,12 +27,12 @@ module Fortnox
|
|
|
27
27
|
attr :delivery_state, DeliveryStates
|
|
28
28
|
|
|
29
29
|
# OrderType Type of order.
|
|
30
|
-
attr :order_type,
|
|
30
|
+
attr :order_type, UnsizedString
|
|
31
31
|
|
|
32
32
|
# StockPointCode Code of the stock point.
|
|
33
|
-
attr :stock_point_code,
|
|
33
|
+
attr :stock_point_code, UnsizedString
|
|
34
34
|
|
|
35
35
|
# StockPointId ID of the stock point.
|
|
36
|
-
attr :stock_point_id,
|
|
36
|
+
attr :stock_point_id, UnsizedString
|
|
37
37
|
end
|
|
38
38
|
end
|
|
@@ -12,7 +12,7 @@ module Fortnox
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# @url Direct URL to the record.
|
|
15
|
-
attr :url <=> '@url',
|
|
15
|
+
attr :url <=> '@url', UnsizedString, :read_only
|
|
16
16
|
|
|
17
17
|
# Code The code of the term of payment.
|
|
18
18
|
key :code, Sized::String[25], :required
|
|
@@ -10,13 +10,13 @@ module Fortnox
|
|
|
10
10
|
attribute? :article_number, Types::Sized::String[50]
|
|
11
11
|
|
|
12
12
|
# ContributionPercent Contribution Percent.
|
|
13
|
-
attribute? :contribution_percent, Types::
|
|
13
|
+
attribute? :contribution_percent, Types::UnsizedFloat, :read_only
|
|
14
14
|
|
|
15
15
|
# ContributionValue Contribution Value.
|
|
16
|
-
attribute? :contribution_value, Types::
|
|
16
|
+
attribute? :contribution_value, Types::UnsizedFloat, :read_only
|
|
17
17
|
|
|
18
18
|
# CostCenter Code of the cost center for the row.
|
|
19
|
-
attribute? :cost_center, Types::
|
|
19
|
+
attribute? :cost_center, Types::UnsizedString
|
|
20
20
|
|
|
21
21
|
# DeliveredQuantity Delivered quantity. 14 digits
|
|
22
22
|
attribute? :delivered_quantity, Types::Sized::Float[-9_999_999_999_999.9, 9_999_999_999_999.9]
|
|
@@ -47,16 +47,16 @@ module Fortnox
|
|
|
47
47
|
attribute? :price, Types::Sized::Float[-99_999_999_999.9, 99_999_999_999.9]
|
|
48
48
|
|
|
49
49
|
# Project Code of the project for the row.
|
|
50
|
-
attribute? :project, Types::
|
|
50
|
+
attribute? :project, Types::UnsizedString
|
|
51
51
|
|
|
52
52
|
# Total Total amount for the row.
|
|
53
|
-
attribute? :total, Types::
|
|
53
|
+
attribute? :total, Types::UnsizedFloat, :read_only
|
|
54
54
|
|
|
55
55
|
# Unit Code of the unit for the row.
|
|
56
|
-
attribute? :unit, Types::
|
|
56
|
+
attribute? :unit, Types::UnsizedString
|
|
57
57
|
|
|
58
58
|
# VAT VAT percentage of the row.
|
|
59
|
-
attribute? :vat, Types::
|
|
59
|
+
attribute? :vat, Types::UnsizedInteger
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
end
|
|
@@ -4,22 +4,22 @@ module Fortnox
|
|
|
4
4
|
module Structs
|
|
5
5
|
class EDIInformation < Fortnox::Struct
|
|
6
6
|
# EDIGlobalLocationNumber Invoice address GLN for EDI
|
|
7
|
-
attribute? :edi_global_location_number, Types::
|
|
7
|
+
attribute? :edi_global_location_number, Types::UnsizedString
|
|
8
8
|
|
|
9
9
|
# EDIGlobalLocationNumberDelivery Delivery address GLN for EDI
|
|
10
|
-
attribute? :edi_global_location_number_delivery, Types::
|
|
10
|
+
attribute? :edi_global_location_number_delivery, Types::UnsizedString
|
|
11
11
|
|
|
12
12
|
# EDIInvoiceExtra1 Extra EDI Information
|
|
13
|
-
attribute? :edi_invoice_extra1, Types::
|
|
13
|
+
attribute? :edi_invoice_extra1, Types::UnsizedString
|
|
14
14
|
|
|
15
15
|
# EDIInvoiceExtra2 Extra EDI Information
|
|
16
|
-
attribute? :edi_invoice_extra2, Types::
|
|
16
|
+
attribute? :edi_invoice_extra2, Types::UnsizedString
|
|
17
17
|
|
|
18
18
|
# EDIOurElectronicReference Our electronic reference for EDI
|
|
19
|
-
attribute? :edi_our_electronic_reference, Types::
|
|
19
|
+
attribute? :edi_our_electronic_reference, Types::UnsizedString
|
|
20
20
|
|
|
21
21
|
# EDIYourElectronicReference Your electronic reference for EDI
|
|
22
|
-
attribute? :edi_your_electronic_reference, Types::
|
|
22
|
+
attribute? :edi_your_electronic_reference, Types::UnsizedString
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -4,10 +4,10 @@ module Fortnox
|
|
|
4
4
|
module Structs
|
|
5
5
|
class InvoiceRow < DocumentRow
|
|
6
6
|
# PriceExcludingVAT Price per unit excluding VAT.
|
|
7
|
-
attribute? :price_excluding_vat, Types::
|
|
7
|
+
attribute? :price_excluding_vat, Types::UnsizedFloat, :read_only
|
|
8
8
|
|
|
9
9
|
# TotalExcludingVAT Total amount for the row excluding VAT.
|
|
10
|
-
attribute? :total_excluding_vat, Types::
|
|
10
|
+
attribute? :total_excluding_vat, Types::UnsizedFloat, :read_only
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
data/lib/fortnox/types.rb
CHANGED
|
@@ -94,35 +94,65 @@ module Fortnox
|
|
|
94
94
|
'', 'none', 'rot', 'rut', 'green'
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
+
# Fortnox silently ignores "" in update payloads — updating an
|
|
98
|
+
# attribute to '' keeps the original value; only an explicit null
|
|
99
|
+
# clears it. On reads, Fortnox spells "unset" as "" or null depending
|
|
100
|
+
# on endpoint and record history. Normalise at the type boundary:
|
|
101
|
+
# blank coerces to nil on parse and update alike, so "no value" is
|
|
102
|
+
# always nil in the model and always null on the wire. (Enum types
|
|
103
|
+
# that include '' as a valid member are exempt on purpose.)
|
|
104
|
+
BLANK_TO_NIL = ->(value) { value == '' ? nil : value }
|
|
105
|
+
|
|
97
106
|
# Fortnox sometimes returns "" for unset attributes using AccountNumber as type.
|
|
98
|
-
# Without
|
|
107
|
+
# Without the blank normalisation, "" falls through to Coercible::Integer and
|
|
99
108
|
# `Integer("")` raises, surfacing as Fortnox::ConstraintError.
|
|
100
109
|
AccountNumber = Coercible::Integer
|
|
101
110
|
.constrained(gteq: 0, lteq: 9999)
|
|
102
111
|
.optional
|
|
103
|
-
.constructor
|
|
112
|
+
.constructor(BLANK_TO_NIL)
|
|
104
113
|
|
|
105
114
|
Email = Strict::String
|
|
106
|
-
.constrained(max_size: 1024, format: /\A
|
|
115
|
+
.constrained(max_size: 1024, format: /\A[[[:alnum:]]+-_.]+@[[[:alnum:]]+-_.]+\.[a-z]+\z/i)
|
|
107
116
|
.optional
|
|
108
|
-
.constructor { |
|
|
117
|
+
.constructor { |value| BLANK_TO_NIL[value]&.to_s&.downcase }
|
|
118
|
+
|
|
119
|
+
UnsizedString = Types::Coercible::String
|
|
120
|
+
.optional
|
|
121
|
+
.constructor(BLANK_TO_NIL)
|
|
122
|
+
|
|
123
|
+
UnsizedInteger = Types::Coercible::Integer
|
|
124
|
+
.optional
|
|
125
|
+
.constructor(BLANK_TO_NIL)
|
|
126
|
+
|
|
127
|
+
UnsizedFloat = Types::Coercible::Float
|
|
128
|
+
.optional
|
|
129
|
+
.constructor(BLANK_TO_NIL)
|
|
109
130
|
|
|
110
131
|
module Sized
|
|
111
132
|
module String
|
|
112
133
|
def self.[](size)
|
|
113
|
-
Types::Coercible::String
|
|
134
|
+
Types::Coercible::String
|
|
135
|
+
.constrained(max_size: size)
|
|
136
|
+
.optional
|
|
137
|
+
.constructor(BLANK_TO_NIL)
|
|
114
138
|
end
|
|
115
139
|
end
|
|
116
140
|
|
|
117
141
|
module Integer
|
|
118
142
|
def self.[](low, high)
|
|
119
|
-
Types::Coercible::Integer
|
|
143
|
+
Types::Coercible::Integer
|
|
144
|
+
.constrained(gteq: low, lteq: high)
|
|
145
|
+
.optional
|
|
146
|
+
.constructor(BLANK_TO_NIL)
|
|
120
147
|
end
|
|
121
148
|
end
|
|
122
149
|
|
|
123
150
|
module Float
|
|
124
151
|
def self.[](low, high)
|
|
125
|
-
Types::Coercible::Float
|
|
152
|
+
Types::Coercible::Float
|
|
153
|
+
.constrained(gteq: low, lteq: high)
|
|
154
|
+
.optional
|
|
155
|
+
.constructor(BLANK_TO_NIL)
|
|
126
156
|
end
|
|
127
157
|
end
|
|
128
158
|
end
|
data/lib/fortnox/version.rb
CHANGED
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.rc13
|
|
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-
|
|
14
|
+
date: 2026-08-04 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: base64
|