fortnox-api 0.8.0 → 0.8.1
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/.codeclimate.yml +1 -0
- data/.rubocop.yml +1 -1
- data/.tool-versions +1 -0
- data/.travis.yml +5 -3
- data/CHANGELOG.md +37 -3
- data/fortnox-api.gemspec +22 -17
- data/lib/fortnox/api/mappers/article.rb +1 -1
- data/lib/fortnox/api/mappers/base/from_json.rb +1 -1
- data/lib/fortnox/api/mappers/base/to_json.rb +2 -2
- data/lib/fortnox/api/mappers/base.rb +3 -3
- data/lib/fortnox/api/mappers/customer.rb +1 -1
- data/lib/fortnox/api/mappers/default_delivery_types.rb +1 -1
- data/lib/fortnox/api/mappers/default_templates.rb +1 -1
- data/lib/fortnox/api/mappers/edi_information.rb +1 -1
- data/lib/fortnox/api/mappers/email_information.rb +1 -1
- data/lib/fortnox/api/mappers/invoice.rb +4 -4
- data/lib/fortnox/api/mappers/invoice_row.rb +1 -1
- data/lib/fortnox/api/mappers/order.rb +4 -4
- data/lib/fortnox/api/mappers/order_row.rb +1 -1
- data/lib/fortnox/api/mappers/project.rb +1 -1
- data/lib/fortnox/api/mappers/terms_of_payment.rb +1 -1
- data/lib/fortnox/api/mappers/unit.rb +1 -1
- data/lib/fortnox/api/mappers/value/country_string.rb +1 -1
- data/lib/fortnox/api/mappers.rb +18 -18
- data/lib/fortnox/api/models/article.rb +2 -2
- data/lib/fortnox/api/models/base.rb +14 -14
- data/lib/fortnox/api/models/customer.rb +2 -2
- data/lib/fortnox/api/models/document.rb +2 -2
- data/lib/fortnox/api/models/invoice.rb +2 -2
- data/lib/fortnox/api/models/label.rb +1 -1
- data/lib/fortnox/api/models/order.rb +2 -2
- data/lib/fortnox/api/models/project.rb +2 -2
- data/lib/fortnox/api/models/terms_of_payment.rb +2 -2
- data/lib/fortnox/api/models/unit.rb +2 -2
- data/lib/fortnox/api/models.rb +7 -7
- data/lib/fortnox/api/repositories/article.rb +3 -3
- data/lib/fortnox/api/repositories/base.rb +4 -3
- data/lib/fortnox/api/repositories/customer.rb +3 -3
- data/lib/fortnox/api/repositories/invoice.rb +3 -3
- data/lib/fortnox/api/repositories/order.rb +3 -3
- data/lib/fortnox/api/repositories/project.rb +3 -3
- data/lib/fortnox/api/repositories/terms_of_payment.rb +3 -3
- data/lib/fortnox/api/repositories/unit.rb +3 -3
- data/lib/fortnox/api/repositories.rb +7 -7
- data/lib/fortnox/api/types/default_delivery_types.rb +0 -2
- data/lib/fortnox/api/types/default_templates.rb +0 -2
- data/lib/fortnox/api/types/edi_information.rb +0 -2
- data/lib/fortnox/api/types/email_information.rb +0 -2
- data/lib/fortnox/api/types/invoice_row.rb +1 -1
- data/lib/fortnox/api/types/model.rb +4 -6
- data/lib/fortnox/api/types/nullable.rb +13 -9
- data/lib/fortnox/api/types/order_row.rb +1 -1
- data/lib/fortnox/api/types/required.rb +3 -3
- data/lib/fortnox/api/types/sized.rb +2 -2
- data/lib/fortnox/api/types.rb +17 -22
- data/lib/fortnox/api/version.rb +1 -1
- data/lib/fortnox/api.rb +18 -16
- data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +9 -7
- data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +1 -1
- data/spec/fortnox/api/mappers/examples/mapper.rb +1 -1
- data/spec/fortnox/api/models/base_spec.rb +8 -8
- data/spec/fortnox/api/repositories/article_spec.rb +2 -2
- data/spec/fortnox/api/repositories/base_spec.rb +4 -12
- data/spec/fortnox/api/repositories/customer_spec.rb +1 -1
- data/spec/fortnox/api/repositories/invoice_spec.rb +0 -6
- data/spec/fortnox/api/repositories/project_spec.rb +1 -1
- data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +2 -2
- data/spec/fortnox/api/repositories/unit_spec.rb +3 -3
- data/spec/fortnox/api/types/housework_types_spec.rb +0 -29
- data/spec/fortnox/api/types/model_spec.rb +11 -17
- data/spec/fortnox/api/types/nullable_spec.rb +30 -10
- data/spec/fortnox/api/types/required_spec.rb +1 -4
- data/spec/support/matchers/type/enum_matcher.rb +1 -1
- data/spec/support/matchers/type/have_account_number_matcher.rb +1 -1
- data/spec/support/matchers/type/have_email_matcher.rb +1 -1
- data/spec/support/matchers/type/have_nullable_date_matcher.rb +5 -5
- data/spec/support/matchers/type/have_nullable_string_matcher.rb +3 -3
- data/spec/vcr_cassettes/articles/all.yml +30 -20
- data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +25 -19
- data/spec/vcr_cassettes/articles/find_failure.yml +25 -19
- data/spec/vcr_cassettes/articles/find_id_1.yml +26 -20
- data/spec/vcr_cassettes/articles/find_new.yml +28 -22
- data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/articles/save_new.yml +27 -21
- data/spec/vcr_cassettes/articles/save_old.yml +28 -22
- data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +27 -21
- data/spec/vcr_cassettes/articles/search_by_name.yml +25 -19
- data/spec/vcr_cassettes/articles/search_miss.yml +25 -19
- data/spec/vcr_cassettes/articles/search_with_special_char.yml +25 -19
- data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +28 -21
- data/spec/vcr_cassettes/customers/all.yml +26 -20
- data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +25 -19
- data/spec/vcr_cassettes/customers/find_failure.yml +25 -19
- data/spec/vcr_cassettes/customers/find_id_1.yml +25 -19
- data/spec/vcr_cassettes/customers/find_new.yml +27 -21
- data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/customers/save_new.yml +26 -20
- data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +26 -20
- data/spec/vcr_cassettes/customers/save_old.yml +27 -21
- data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +26 -20
- data/spec/vcr_cassettes/customers/search_by_name.yml +28 -20
- data/spec/vcr_cassettes/customers/search_miss.yml +25 -19
- data/spec/vcr_cassettes/customers/search_with_special_char.yml +25 -19
- data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/invoices/all.yml +26 -20
- data/spec/vcr_cassettes/invoices/filter_hit.yml +25 -19
- data/spec/vcr_cassettes/invoices/filter_invalid.yml +25 -19
- data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +25 -19
- data/spec/vcr_cassettes/invoices/find_failure.yml +25 -19
- data/spec/vcr_cassettes/invoices/find_id_1.yml +26 -20
- data/spec/vcr_cassettes/invoices/find_new.yml +30 -24
- data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/invoices/save_new.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_new_with_country.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_old.yml +30 -24
- data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +30 -24
- data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +30 -24
- data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +29 -23
- data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +28 -22
- data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +28 -22
- data/spec/vcr_cassettes/invoices/search_by_name.yml +25 -19
- data/spec/vcr_cassettes/invoices/search_miss.yml +25 -19
- data/spec/vcr_cassettes/invoices/search_with_special_char.yml +25 -19
- data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/orders/all.yml +26 -20
- data/spec/vcr_cassettes/orders/filter_hit.yml +25 -19
- data/spec/vcr_cassettes/orders/filter_invalid.yml +25 -19
- data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +25 -19
- data/spec/vcr_cassettes/orders/find_failure.yml +25 -19
- data/spec/vcr_cassettes/orders/find_id_1.yml +25 -19
- data/spec/vcr_cassettes/orders/find_new.yml +29 -23
- data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +25 -19
- data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +25 -19
- data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_construction.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_cooking.yml +25 -19
- data/spec/vcr_cassettes/orders/housework_type_electricity.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_gardening.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_hvac.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_itservices.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_masonry.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_othercare.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +28 -22
- data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +25 -19
- data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/orders/save_new.yml +28 -22
- data/spec/vcr_cassettes/orders/save_old.yml +29 -23
- data/spec/vcr_cassettes/orders/save_with_nested_model.yml +28 -22
- data/spec/vcr_cassettes/orders/search_by_name.yml +25 -19
- data/spec/vcr_cassettes/orders/search_miss.yml +25 -19
- data/spec/vcr_cassettes/orders/search_with_special_char.yml +25 -19
- data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +25 -19
- data/spec/vcr_cassettes/projects/all.yml +31 -21
- data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +25 -19
- data/spec/vcr_cassettes/projects/find_failure.yml +25 -19
- data/spec/vcr_cassettes/projects/find_id_1.yml +25 -19
- data/spec/vcr_cassettes/projects/find_new.yml +28 -22
- data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +26 -20
- data/spec/vcr_cassettes/projects/save_new.yml +27 -21
- data/spec/vcr_cassettes/projects/save_old.yml +28 -22
- data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +26 -20
- data/spec/vcr_cassettes/termsofpayments/all.yml +34 -27
- data/spec/vcr_cassettes/termsofpayments/find_failure.yml +25 -19
- data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +25 -19
- data/spec/vcr_cassettes/termsofpayments/find_new.yml +27 -21
- data/spec/vcr_cassettes/termsofpayments/save_new.yml +27 -21
- data/spec/vcr_cassettes/termsofpayments/save_old.yml +27 -21
- data/spec/vcr_cassettes/units/all.yml +36 -28
- data/spec/vcr_cassettes/units/find_failure.yml +25 -19
- data/spec/vcr_cassettes/units/find_id_1.yml +26 -20
- data/spec/vcr_cassettes/units/find_new.yml +27 -21
- data/spec/vcr_cassettes/units/save_new.yml +27 -21
- data/spec/vcr_cassettes/units/save_old.yml +27 -21
- data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +27 -21
- metadata +107 -47
- data/spec/support/helpers/dummy_class_helper.rb +0 -38
- data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +0 -61
- data/spec/vcr_cassettes/orders/housework_without_tax_reduction_type.yml +0 -57
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative '../models/order'
|
5
|
+
require_relative '../mappers/order'
|
6
6
|
|
7
7
|
module Fortnox
|
8
8
|
module API
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative '../models/project'
|
5
|
+
require_relative '../mappers/project'
|
6
6
|
|
7
7
|
module Fortnox
|
8
8
|
module API
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative '../models/terms_of_payment'
|
5
|
+
require_relative '../mappers/terms_of_payment'
|
6
6
|
|
7
7
|
module Fortnox
|
8
8
|
module API
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative '../models/unit'
|
5
|
+
require_relative '../mappers/unit'
|
6
6
|
|
7
7
|
module Fortnox
|
8
8
|
module API
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
require_relative 'repositories/article'
|
4
|
+
require_relative 'repositories/customer'
|
5
|
+
require_relative 'repositories/invoice'
|
6
|
+
require_relative 'repositories/order'
|
7
|
+
require_relative 'repositories/project'
|
8
|
+
require_relative 'repositories/unit'
|
9
|
+
require_relative 'repositories/terms_of_payment'
|
@@ -4,7 +4,7 @@ module Fortnox
|
|
4
4
|
module API
|
5
5
|
module Types
|
6
6
|
class Model < Dry::Struct
|
7
|
-
|
7
|
+
transform_types(&:omittable)
|
8
8
|
|
9
9
|
def initialize(input_attributes)
|
10
10
|
if (missing_key = first_missing_required_key(input_attributes))
|
@@ -15,23 +15,21 @@ module Fortnox
|
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.is?(*_args) end
|
19
|
-
|
20
18
|
private
|
21
19
|
|
22
20
|
def missing_keys(attributes)
|
23
21
|
non_nil_attributes = attributes.reject { |_, value| value.nil? }
|
24
22
|
|
25
23
|
attribute_keys = non_nil_attributes.keys
|
26
|
-
schema_keys =
|
24
|
+
schema_keys = self.class.schema.keys.map(&:name)
|
27
25
|
|
28
26
|
schema_keys - attribute_keys
|
29
27
|
end
|
30
28
|
|
31
29
|
def first_missing_required_key(attributes)
|
32
30
|
missing_keys(attributes).find do |name|
|
33
|
-
attribute = self.class.schema
|
34
|
-
attribute.respond_to?(:options) && attribute.options[:required]
|
31
|
+
attribute = self.class.schema.keys.find { |key| key.name == name }
|
32
|
+
attribute.type.respond_to?(:options) && attribute.type.options[:required]
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
@@ -6,15 +6,19 @@ module Fortnox
|
|
6
6
|
module API
|
7
7
|
module Types
|
8
8
|
module Nullable
|
9
|
-
String = Types::Strict::String.optional.constructor { |value| value
|
10
|
-
Float = Types::Strict::Float.optional.constructor { |value| value
|
11
|
-
Integer = Types::Strict::
|
12
|
-
Boolean = Types::Bool.optional.constructor { |value| THE_TRUTH.fetch(value
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
9
|
+
String = Types::Strict::String.optional.constructor { |value| value&.to_s }
|
10
|
+
Float = Types::Strict::Float.optional.constructor { |value| value&.to_f }
|
11
|
+
Integer = Types::Strict::Integer.optional.constructor { |value| value&.to_i }
|
12
|
+
Boolean = Types::Bool.optional.constructor { |value| THE_TRUTH.fetch(value, false) }
|
13
|
+
Date = Types::Date.optional.constructor do |value|
|
14
|
+
next if value.nil? || value == ''
|
15
|
+
|
16
|
+
begin
|
17
|
+
::Date.parse(value.to_s)
|
18
|
+
rescue ::Date::Error
|
19
|
+
raise Fortnox::API::AttributeError, 'invalid date'
|
20
|
+
end
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -4,9 +4,9 @@ module Fortnox
|
|
4
4
|
module API
|
5
5
|
module Types
|
6
6
|
module Required
|
7
|
-
String = Types::Strict::String.constructor { |value| value
|
8
|
-
Integer = Types::Strict::
|
9
|
-
Float = Types::Strict::Float.constructor { |value| value
|
7
|
+
String = Types::Strict::String.constructor { |value| value&.to_s }.is(:required)
|
8
|
+
Integer = Types::Strict::Integer.constructor { |value| value&.to_i }.is(:required)
|
9
|
+
Float = Types::Strict::Float.constructor { |value| value&.to_f }.is(:required)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -14,8 +14,8 @@ module Fortnox
|
|
14
14
|
|
15
15
|
module Integer
|
16
16
|
def self.[](low, high)
|
17
|
-
Types::Strict::
|
18
|
-
value
|
17
|
+
Types::Strict::Integer.constrained(gteq: low, lteq: high).optional.constructor do |value|
|
18
|
+
value&.to_i
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/fortnox/api/types.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'dry-struct'
|
4
4
|
require 'dry-types'
|
5
5
|
require 'countries'
|
6
|
-
|
6
|
+
require_relative 'types/shim/country_string'
|
7
7
|
|
8
8
|
module Dry
|
9
9
|
module Types
|
@@ -12,11 +12,7 @@ module Dry
|
|
12
12
|
new_options = option_names.each_with_object({}) do |name, hash|
|
13
13
|
hash[name] = true
|
14
14
|
end
|
15
|
-
with(new_options)
|
16
|
-
end
|
17
|
-
|
18
|
-
def is?(option_name)
|
19
|
-
@options[option_name]
|
15
|
+
with(**new_options)
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
@@ -25,20 +21,19 @@ end
|
|
25
21
|
module Fortnox
|
26
22
|
module API
|
27
23
|
module Types
|
28
|
-
include Dry
|
24
|
+
include Dry.Types(default: :nominal)
|
29
25
|
ISO3166.configure { |config| config.locales = %i[en sv] }
|
30
26
|
|
31
27
|
THE_TRUTH = { true => true, 'true' => true, false => false, 'false' => false }.freeze
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
require 'fortnox/api/types/enums'
|
29
|
+
require_relative 'types/required'
|
30
|
+
require_relative 'types/defaulted'
|
31
|
+
require_relative 'types/nullable'
|
38
32
|
|
39
|
-
|
33
|
+
require_relative 'types/enums'
|
34
|
+
require_relative 'types/sized'
|
40
35
|
|
41
|
-
AccountNumber = Strict::
|
36
|
+
AccountNumber = Strict::Integer
|
42
37
|
.constrained(gteq: 0, lteq: 9999)
|
43
38
|
.optional
|
44
39
|
.constructor do |value|
|
@@ -60,7 +55,7 @@ module Fortnox
|
|
60
55
|
next CountryString.new('SE') if value.match?(/^s(e$|we|ve)/i)
|
61
56
|
|
62
57
|
country = ::ISO3166::Country[value] ||
|
63
|
-
::ISO3166::Country.
|
58
|
+
::ISO3166::Country.find_country_by_any_name(value) ||
|
64
59
|
::ISO3166::Country.find_country_by_translated_names(value)
|
65
60
|
|
66
61
|
raise Dry::Types::ConstraintError.new('value violates constraints', value) if country.nil?
|
@@ -124,13 +119,13 @@ module Fortnox
|
|
124
119
|
.optional
|
125
120
|
.constructor(EnumConstructors.lower_case)
|
126
121
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
122
|
+
require_relative 'types/model'
|
123
|
+
require_relative 'types/default_delivery_types'
|
124
|
+
require_relative 'types/default_templates'
|
125
|
+
require_relative 'types/email_information'
|
126
|
+
require_relative 'types/edi_information'
|
127
|
+
require_relative 'types/invoice_row'
|
128
|
+
require_relative 'types/order_row'
|
134
129
|
end
|
135
130
|
end
|
136
131
|
end
|
data/lib/fortnox/api/version.rb
CHANGED
data/lib/fortnox/api.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'set'
|
4
|
-
require 'dry-
|
5
|
-
require '
|
6
|
-
require 'fortnox/api/version'
|
4
|
+
require 'dry-configurable'
|
5
|
+
require 'dry-container'
|
7
6
|
require 'logger'
|
8
7
|
|
8
|
+
require_relative 'api/circular_queue'
|
9
|
+
require_relative 'api/version'
|
10
|
+
|
9
11
|
module Fortnox
|
10
12
|
module API
|
11
13
|
extend Dry::Configurable
|
@@ -18,29 +20,29 @@ module Fortnox
|
|
18
20
|
access_tokens: nil,
|
19
21
|
debugging: false,
|
20
22
|
logger: lambda {
|
21
|
-
logger = Logger.new(
|
23
|
+
logger = Logger.new($stdout)
|
22
24
|
logger.level = Logger::WARN
|
23
25
|
return logger
|
24
26
|
}.call
|
25
27
|
}.freeze
|
26
28
|
|
27
|
-
setting :base_url, DEFAULT_CONFIGURATION[:base_url]
|
28
|
-
setting :client_secret, DEFAULT_CONFIGURATION[:client_secret]
|
29
|
-
setting :token_store, DEFAULT_CONFIGURATION[:token_store]
|
30
|
-
setting :access_token, DEFAULT_CONFIGURATION[:access_token] do |value|
|
29
|
+
setting :base_url, default: DEFAULT_CONFIGURATION[:base_url]
|
30
|
+
setting :client_secret, default: DEFAULT_CONFIGURATION[:client_secret]
|
31
|
+
setting :token_store, default: DEFAULT_CONFIGURATION[:token_store]
|
32
|
+
setting :access_token, default: DEFAULT_CONFIGURATION[:access_token], constructor: (proc do |value|
|
31
33
|
next if value.nil? # nil is a valid unassigned value
|
32
34
|
invalid_access_token_format!(value) unless value.is_a?(String)
|
33
35
|
config.token_store = { default: value }
|
34
36
|
value
|
35
|
-
end
|
36
|
-
setting :access_tokens, DEFAULT_CONFIGURATION[:access_tokens] do |value|
|
37
|
+
end)
|
38
|
+
setting :access_tokens, default: DEFAULT_CONFIGURATION[:access_tokens], constructor: (proc do |value|
|
37
39
|
next if value.nil? # nil is a valid unassigned value
|
38
40
|
invalid_access_tokens_format!(value) unless value.is_a?(Hash) || value.is_a?(Array)
|
39
41
|
config.token_store = value.is_a?(Hash) ? value : { default: value }
|
40
42
|
value
|
41
|
-
end
|
42
|
-
setting :debugging, DEFAULT_CONFIGURATION[:debugging], reader: true
|
43
|
-
setting :logger, DEFAULT_CONFIGURATION[:logger], reader: true
|
43
|
+
end)
|
44
|
+
setting :debugging, default: DEFAULT_CONFIGURATION[:debugging], reader: true
|
45
|
+
setting :logger, default: DEFAULT_CONFIGURATION[:logger], reader: true
|
44
46
|
|
45
47
|
class Exception < StandardError
|
46
48
|
end
|
@@ -75,6 +77,6 @@ module Fortnox
|
|
75
77
|
end
|
76
78
|
end
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
require_relative 'api/models'
|
81
|
+
require_relative 'api/repositories'
|
82
|
+
require_relative 'api/mappers'
|
@@ -6,10 +6,12 @@ require 'fortnox/api/mappers/base/canonical_name_sym'
|
|
6
6
|
describe Fortnox::API::Mapper::CanonicalNameSym do
|
7
7
|
describe '.canonical_name_sym' do
|
8
8
|
context 'with simple class' do
|
9
|
-
|
10
|
-
|
9
|
+
before do
|
10
|
+
test_class = Class.new do
|
11
11
|
extend Fortnox::API::Mapper::CanonicalNameSym
|
12
12
|
end
|
13
|
+
|
14
|
+
stub_const('TestClass', test_class)
|
13
15
|
end
|
14
16
|
|
15
17
|
subject { TestClass.canonical_name_sym }
|
@@ -18,12 +20,12 @@ describe Fortnox::API::Mapper::CanonicalNameSym do
|
|
18
20
|
end
|
19
21
|
|
20
22
|
context 'when class included in module' do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
extend Fortnox::API::Mapper::CanonicalNameSym
|
25
|
-
end
|
23
|
+
before do
|
24
|
+
test_class = Class.new do
|
25
|
+
extend Fortnox::API::Mapper::CanonicalNameSym
|
26
26
|
end
|
27
|
+
|
28
|
+
stub_const('Something::Test', test_class)
|
27
29
|
end
|
28
30
|
|
29
31
|
subject { Something::Test.canonical_name_sym }
|
@@ -8,7 +8,7 @@ require 'fortnox/api/mappers/examples/mapper'
|
|
8
8
|
describe Fortnox::API::Mapper::DefaultDeliveryTypes do
|
9
9
|
key_map = {}
|
10
10
|
|
11
|
-
it_behaves_like 'mapper', key_map do
|
11
|
+
it_behaves_like 'mapper', key_map, nil, nil do
|
12
12
|
let(:mapper) { described_class.new }
|
13
13
|
end
|
14
14
|
end
|
@@ -12,7 +12,7 @@ shared_examples_for 'mapper' do |key_map, json_entity_wrapper = nil, json_collec
|
|
12
12
|
describe 'key_map' do
|
13
13
|
subject { described_class::KEY_MAP }
|
14
14
|
|
15
|
-
it {
|
15
|
+
it { expect(subject).to eq(key_map) }
|
16
16
|
end
|
17
17
|
|
18
18
|
unless json_entity_wrapper.nil?
|
@@ -5,8 +5,8 @@ require 'fortnox/api/models/base'
|
|
5
5
|
require 'fortnox/api/types'
|
6
6
|
|
7
7
|
describe Fortnox::API::Model::Base do
|
8
|
-
|
9
|
-
|
8
|
+
let(:entity_class) do
|
9
|
+
Class.new(Fortnox::API::Model::Base) do
|
10
10
|
attribute :private, Fortnox::API::Types::String.is(:read_only)
|
11
11
|
attribute :string, Fortnox::API::Types::Required::String
|
12
12
|
attribute :number, Fortnox::API::Types::Nullable::Integer
|
@@ -16,15 +16,15 @@ describe Fortnox::API::Model::Base do
|
|
16
16
|
|
17
17
|
describe '.new' do
|
18
18
|
context 'with basic attribute' do
|
19
|
-
subject {
|
19
|
+
subject { entity_class.new(string: 'Test') }
|
20
20
|
|
21
|
-
it { is_expected.to be_a
|
21
|
+
it { is_expected.to be_a entity_class }
|
22
22
|
it { is_expected.to be_new }
|
23
23
|
it { is_expected.not_to be_saved }
|
24
24
|
end
|
25
25
|
|
26
26
|
context 'without required attribute' do
|
27
|
-
subject { -> {
|
27
|
+
subject { -> { entity_class.new({}) } }
|
28
28
|
|
29
29
|
it { is_expected.to raise_error Fortnox::API::Exception }
|
30
30
|
it { is_expected.to raise_error Fortnox::API::MissingAttributeError }
|
@@ -32,7 +32,7 @@ describe Fortnox::API::Model::Base do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
context 'with invalid attribute value' do
|
35
|
-
subject { -> {
|
35
|
+
subject { -> { entity_class.new(string: 'Test', account: 13_337) } }
|
36
36
|
|
37
37
|
it { is_expected.to raise_error Fortnox::API::Exception }
|
38
38
|
it { is_expected.to raise_error Fortnox::API::AttributeError }
|
@@ -41,7 +41,7 @@ describe Fortnox::API::Model::Base do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
describe '.update' do
|
44
|
-
let(:original) {
|
44
|
+
let(:original) { entity_class.new(string: 'Test') }
|
45
45
|
|
46
46
|
context 'with new, simple value' do
|
47
47
|
subject { updated_model }
|
@@ -85,7 +85,7 @@ describe Fortnox::API::Model::Base do
|
|
85
85
|
|
86
86
|
context 'when updating' do
|
87
87
|
let(:updated_entity) do
|
88
|
-
saved_entity =
|
88
|
+
saved_entity = entity_class.new(string: 'Saved', new: false, unsaved: false)
|
89
89
|
saved_entity.update(string: 'Updated')
|
90
90
|
end
|
91
91
|
|
@@ -27,12 +27,12 @@ describe Fortnox::API::Repository::Article, order: :defined, integration: true d
|
|
27
27
|
'5901234123457'
|
28
28
|
|
29
29
|
# When recording new VCR cassettes, expected matches must be increased
|
30
|
-
include_examples '.all',
|
30
|
+
include_examples '.all', 33
|
31
31
|
|
32
32
|
# When recording new VCR cassettes, expected matches must be increased
|
33
33
|
include_examples '.find', '1' do
|
34
34
|
let(:find_by_hash_failure) { { description: 'Not Found' } }
|
35
|
-
let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches:
|
35
|
+
let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches: 14 } }
|
36
36
|
|
37
37
|
let(:multi_param_find_by_hash) do
|
38
38
|
{ find_hash: { articlenumber: 1, description: 'Cykelpump' }, matches: 1 }
|
@@ -4,19 +4,11 @@ require 'spec_helper'
|
|
4
4
|
require 'fortnox/api'
|
5
5
|
|
6
6
|
describe Fortnox::API::Repository::Base do
|
7
|
-
using_test_class do
|
8
|
-
module Model
|
9
|
-
class RepositoryBaseTest
|
10
|
-
end
|
11
|
-
end
|
12
|
-
module Repository
|
13
|
-
class Test < Fortnox::API::Repository::Base
|
14
|
-
MODEL = Model::RepositoryBaseTest
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
7
|
before do
|
8
|
+
stub_const('Model::RepositoryBaseTest', Class.new)
|
9
|
+
stub_const('Repository::Test', Class.new(described_class))
|
10
|
+
stub_const('Repository::Test::MODEL', Model::RepositoryBaseTest)
|
11
|
+
|
20
12
|
Fortnox::API::Registry.register(:repositorybasetest, Model::RepositoryBaseTest)
|
21
13
|
end
|
22
14
|
|
@@ -39,7 +39,7 @@ describe Fortnox::API::Repository::Customer, order: :defined, integration: true
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# When recording new VCR casettes, expected matches must be increased
|
42
|
-
include_examples '.search', :name, 'Test',
|
42
|
+
include_examples '.search', :name, 'Test', 33
|
43
43
|
|
44
44
|
describe 'country reference' do
|
45
45
|
describe 'with valid country code \'SE\'' do
|
@@ -89,12 +89,6 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
|
|
89
89
|
it { is_expected.to eq('GB') }
|
90
90
|
end
|
91
91
|
|
92
|
-
describe 'KR' do
|
93
|
-
subject { save_invoice(country: 'KR').country }
|
94
|
-
|
95
|
-
it { is_expected.to eq('KR') }
|
96
|
-
end
|
97
|
-
|
98
92
|
describe 'VA' do
|
99
93
|
subject { save_invoice(country: 'VA').country }
|
100
94
|
|
@@ -22,7 +22,7 @@ describe Fortnox::API::Repository::Project, order: :defined, integration: true d
|
|
22
22
|
# It is not yet possible to delete Projects. Therefore, expected nr of
|
23
23
|
# Projects when running .all will continue to increase
|
24
24
|
# (until 100, which is max by default).
|
25
|
-
include_examples '.all',
|
25
|
+
include_examples '.all', 37
|
26
26
|
|
27
27
|
include_examples '.find', '1' do
|
28
28
|
let(:find_by_hash_failure) { { offset: 10_000 } }
|
@@ -18,12 +18,12 @@ describe Fortnox::API::Repository::TermsOfPayment, order: :defined, integration:
|
|
18
18
|
before { set_api_test_configuration }
|
19
19
|
|
20
20
|
# When recording new VCR cassettes, code must be changed to a new unique one
|
21
|
-
required_hash = { code: '
|
21
|
+
required_hash = { code: '20DAYS' }
|
22
22
|
|
23
23
|
include_examples '.save', :description, additional_attrs: required_hash
|
24
24
|
|
25
25
|
# When recording new VCR cassettes, expected matches needs to be increased
|
26
|
-
include_examples '.all',
|
26
|
+
include_examples '.all', 14
|
27
27
|
|
28
28
|
include_examples '.find', '15DAYS', find_by_hash: false do
|
29
29
|
let(:find_by_hash_failure) { { code: '15days' } }
|
@@ -19,16 +19,16 @@ describe Fortnox::API::Repository::Unit, order: :defined, integration: true do
|
|
19
19
|
# When recording new VCR cassettes, code needs to be changed to a unique value
|
20
20
|
include_examples '.save',
|
21
21
|
:description,
|
22
|
-
additional_attrs: { code: '
|
22
|
+
additional_attrs: { code: 'blarg7' }
|
23
23
|
|
24
24
|
# When recording new VCR cassettes, code needs to be changed to a unique value
|
25
25
|
include_examples '.save with specially named attribute',
|
26
26
|
{ description: 'Happy clouds' },
|
27
27
|
:code,
|
28
|
-
'
|
28
|
+
'woooh6'
|
29
29
|
|
30
30
|
# When recording new VCR cassettes, expected number must be updated
|
31
|
-
include_examples '.all',
|
31
|
+
include_examples '.all', 16
|
32
32
|
|
33
33
|
include_examples '.find', 'blarg', find_by_hash: false do
|
34
34
|
let(:find_by_hash_failure) { { code: 'notfound' } }
|
@@ -93,35 +93,6 @@ describe 'HouseworkTypes', integration: true do
|
|
93
93
|
it_behaves_like 'housework type', 'COOKING', TYPE_RUT, legacy: true
|
94
94
|
it_behaves_like 'housework type', 'TUTORING', TYPE_RUT, legacy: true
|
95
95
|
|
96
|
-
describe 'without tax reduction type' do
|
97
|
-
subject do
|
98
|
-
cassette = 'orders/housework_without_tax_reduction_type'
|
99
|
-
-> { VCR.use_cassette(cassette) { repository.save(document) } }
|
100
|
-
end
|
101
|
-
|
102
|
-
let(:document) do
|
103
|
-
Fortnox::API::Model::Order.new(
|
104
|
-
customer_number: '1',
|
105
|
-
order_rows: [
|
106
|
-
Fortnox::API::Types::OrderRow.new(
|
107
|
-
ordered_quantity: 1,
|
108
|
-
article_number: '0000',
|
109
|
-
housework_type: Fortnox::API::Types::HouseworkTypes['CONSTRUCTION'],
|
110
|
-
housework: true
|
111
|
-
)
|
112
|
-
]
|
113
|
-
)
|
114
|
-
end
|
115
|
-
|
116
|
-
let(:error_message) do
|
117
|
-
'Dokument utan angiven skattereduktionstyp får inte innehålla artikelrader med husarbetestyp.'
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'raises an error' do
|
121
|
-
is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
96
|
describe 'with OTHERCOSTS' do
|
126
97
|
subject do
|
127
98
|
cassette = 'orders/housework_othercoses_invalid'
|