fortnox-api 0.7.2 → 0.8.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 +1 -1
- data/.travis.yml +3 -10
- data/CHANGELOG.md +10 -0
- data/README.md +7 -4
- data/Rakefile +5 -0
- data/fortnox-api.gemspec +2 -2
- data/lib/fortnox/api/mappers/base/from_json.rb +2 -2
- data/lib/fortnox/api/models/document.rb +3 -0
- data/lib/fortnox/api/types.rb +6 -1
- data/lib/fortnox/api/types/enums.rb +36 -8
- data/lib/fortnox/api/version.rb +1 -1
- data/spec/fortnox/api/circular_queue_spec.rb +3 -3
- data/spec/fortnox/api/repositories/article_spec.rb +1 -1
- data/spec/fortnox/api/repositories/customer_spec.rb +1 -1
- data/spec/fortnox/api/repositories/invoice_spec.rb +13 -13
- 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/enums_spec.rb +1 -0
- data/spec/fortnox/api/types/housework_types_spec.rb +151 -34
- data/spec/vcr_cassettes/articles/all.yml +25 -9
- data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +20 -7
- data/spec/vcr_cassettes/articles/find_failure.yml +20 -7
- data/spec/vcr_cassettes/articles/find_id_1.yml +21 -8
- data/spec/vcr_cassettes/articles/find_new.yml +23 -10
- data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/articles/save_new.yml +21 -7
- data/spec/vcr_cassettes/articles/save_old.yml +23 -10
- data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +21 -7
- data/spec/vcr_cassettes/articles/search_by_name.yml +20 -7
- data/spec/vcr_cassettes/articles/search_miss.yml +20 -7
- data/spec/vcr_cassettes/articles/search_with_special_char.yml +20 -7
- data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +21 -8
- data/spec/vcr_cassettes/customers/all.yml +22 -9
- data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +20 -7
- data/spec/vcr_cassettes/customers/find_failure.yml +20 -7
- data/spec/vcr_cassettes/customers/find_id_1.yml +20 -7
- data/spec/vcr_cassettes/customers/find_new.yml +22 -9
- data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/customers/save_new.yml +20 -6
- data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +10 -6
- data/spec/vcr_cassettes/customers/save_old.yml +22 -9
- data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +20 -6
- data/spec/vcr_cassettes/customers/search_by_name.yml +22 -8
- data/spec/vcr_cassettes/customers/search_miss.yml +20 -7
- data/spec/vcr_cassettes/customers/search_with_special_char.yml +19 -6
- data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/invoices/all.yml +25 -9
- data/spec/vcr_cassettes/invoices/filter_hit.yml +20 -7
- data/spec/vcr_cassettes/invoices/filter_invalid.yml +19 -5
- data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +20 -7
- data/spec/vcr_cassettes/invoices/find_failure.yml +19 -6
- data/spec/vcr_cassettes/invoices/find_id_1.yml +22 -9
- data/spec/vcr_cassettes/invoices/find_new.yml +24 -11
- data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/invoices/save_new.yml +22 -8
- data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +22 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +12 -8
- data/spec/vcr_cassettes/invoices/save_old.yml +24 -11
- data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +24 -11
- data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +14 -11
- data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +24 -11
- data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +14 -11
- data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +22 -8
- data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +22 -8
- data/spec/vcr_cassettes/invoices/search_by_name.yml +20 -7
- data/spec/vcr_cassettes/invoices/search_miss.yml +20 -7
- data/spec/vcr_cassettes/invoices/search_with_special_char.yml +20 -7
- data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +19 -6
- data/spec/vcr_cassettes/orders/all.yml +21 -8
- data/spec/vcr_cassettes/orders/filter_hit.yml +19 -6
- data/spec/vcr_cassettes/orders/filter_invalid.yml +19 -5
- data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +20 -7
- data/spec/vcr_cassettes/orders/find_failure.yml +20 -7
- data/spec/vcr_cassettes/orders/find_id_1.yml +21 -8
- data/spec/vcr_cassettes/orders/find_new.yml +24 -11
- data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +57 -0
- data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +57 -0
- data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_construction.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_cooking.yml +20 -6
- data/spec/vcr_cassettes/orders/housework_type_electricity.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_gardening.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_hvac.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_itservices.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_masonry.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_othercare.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +23 -9
- data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +20 -6
- data/spec/vcr_cassettes/orders/housework_without_tax_reduction_type.yml +57 -0
- data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/orders/save_new.yml +22 -8
- data/spec/vcr_cassettes/orders/save_old.yml +24 -11
- data/spec/vcr_cassettes/orders/save_with_nested_model.yml +22 -8
- data/spec/vcr_cassettes/orders/search_by_name.yml +20 -7
- data/spec/vcr_cassettes/orders/search_miss.yml +20 -7
- data/spec/vcr_cassettes/orders/search_with_special_char.yml +19 -6
- data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +20 -7
- data/spec/vcr_cassettes/projects/all.yml +40 -25
- data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +20 -7
- data/spec/vcr_cassettes/projects/find_failure.yml +20 -7
- data/spec/vcr_cassettes/projects/find_id_1.yml +20 -7
- data/spec/vcr_cassettes/projects/find_new.yml +23 -10
- data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +22 -9
- data/spec/vcr_cassettes/projects/save_new.yml +21 -7
- data/spec/vcr_cassettes/projects/save_old.yml +23 -10
- data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +22 -9
- data/spec/vcr_cassettes/termsofpayments/all.yml +29 -15
- data/spec/vcr_cassettes/termsofpayments/find_failure.yml +20 -7
- data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +21 -8
- data/spec/vcr_cassettes/termsofpayments/find_new.yml +22 -9
- data/spec/vcr_cassettes/termsofpayments/save_new.yml +21 -7
- data/spec/vcr_cassettes/termsofpayments/save_old.yml +22 -9
- data/spec/vcr_cassettes/units/all.yml +23 -8
- data/spec/vcr_cassettes/units/find_failure.yml +19 -6
- data/spec/vcr_cassettes/units/find_id_1.yml +20 -7
- data/spec/vcr_cassettes/units/find_new.yml +22 -9
- data/spec/vcr_cassettes/units/save_new.yml +21 -7
- data/spec/vcr_cassettes/units/save_old.yml +22 -9
- data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +21 -7
- metadata +20 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02c5fbd6c659d3c6cc4e9ed8dfef6e739ded62fc33107623f4dddc13d33f6672
|
|
4
|
+
data.tar.gz: 14f0815a2fd32e98055d71ef231da2b6fac4b95ecfd9dfcda59b88d1c1445c63
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 293665ff9e0b860e88c7c6c78fbcfdd0b8a8047444f23cd0560d504442e1a0ac3439c52349413cac63e0c5973d1db74dabcf7ebdd9c10bc3f1b7de922db58cbc
|
|
7
|
+
data.tar.gz: 011b4785ce46af9c4cd57939431f6b09dc6ab44d650023616fe7b0784dcde890727999eb918ac3c3db311afaaff8785d240c54e5c30f198a630b9a1bf41483b7
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
|
@@ -3,16 +3,9 @@ env:
|
|
|
3
3
|
- CC_TEST_REPORTER_ID=43ea0acb059b164537ce31bf67e03e1cb552d63df1ad3e9bd95dc3d844697bb4
|
|
4
4
|
language: ruby
|
|
5
5
|
rvm:
|
|
6
|
-
- 2.
|
|
7
|
-
- 2.
|
|
8
|
-
- 2.
|
|
9
|
-
- 2.4.3
|
|
10
|
-
- 2.4.6
|
|
11
|
-
- 2.5.0
|
|
12
|
-
- 2.5.5
|
|
13
|
-
- 2.6.0
|
|
14
|
-
- 2.6.3
|
|
15
|
-
- 2.7.0-preview1
|
|
6
|
+
- 2.5.8
|
|
7
|
+
- 2.6.6
|
|
8
|
+
- 2.7.1
|
|
16
9
|
notifications:
|
|
17
10
|
slack:
|
|
18
11
|
secure: UEYDtwLaQgAoMRY7ct1y0Uu5HbInMwrLo+TiYRc3rjDrzqDfDyInEr3bpckyPJ79lnzccrFezMdY4jWzRjmsvQzvYMu+DWJ1mAWOa/9Ws4YZ8nHd5KqXxVQ0EqPWuWwMOyOdyy3DK/MjUOobGSc0//Pv5DeaAAEBKLJzN+e1BQM=
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.8.0]
|
|
8
|
+
### Changed
|
|
9
|
+
- `Fortnox::API::CURRENT_HOUSEWORK_TYPES` is now renamed to `HOUSEWORK_TYPES`
|
|
10
|
+
and is instead a Hash with keys for the different categories of types.
|
|
11
|
+
It also includes legacy types, which means `Fortnox::API::LEGACY_HOUSEWORK_TYPES` is removed.
|
|
12
|
+
|
|
13
|
+
### Removed
|
|
14
|
+
- Drops support for Ruby < `2.5.0` since they are deprecated
|
|
15
|
+
|
|
7
16
|
## [0.7.2]
|
|
8
17
|
### Fixed
|
|
9
18
|
- Invalid validation for Customer's account number attribute
|
|
@@ -32,6 +41,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
32
41
|
### Fixed
|
|
33
42
|
- Model attribute `url` is no longer null
|
|
34
43
|
|
|
44
|
+
[0.8.0]: https://github.com/accodeing/fortnox-api/compare/v0.7.2...v0.8.0
|
|
35
45
|
[0.7.2]: https://github.com/accodeing/fortnox-api/compare/v0.7.1...v0.7.2
|
|
36
46
|
[0.7.1]: https://github.com/accodeing/fortnox-api/compare/v0.7.0...v0.7.1
|
|
37
47
|
[0.7.0]: https://github.com/accodeing/fortnox-api/compare/v0.6.3...v0.7.0
|
data/README.md
CHANGED
|
@@ -10,14 +10,13 @@
|
|
|
10
10
|
[](https://codeclimate.com/github/accodeing/fortnox-api/maintainability)
|
|
11
11
|
[](https://codeclimate.com/github/accodeing/fortnox-api/test_coverage)
|
|
12
12
|
|
|
13
|
-
The rough status of this project is as follows (as of
|
|
13
|
+
The rough status of this project is as follows (as of December 2020):
|
|
14
14
|
* Development is not as active as it used to be, but the project is not forgotten. We have an app running this gem in production and it works like a charm for what we do.
|
|
15
|
-
* We
|
|
15
|
+
* We hope to be able to continue with our work with [rest_easy gem](https://github.com/accodeing/rest_easy), which generalize REST API's in general.
|
|
16
16
|
* Basic structure complete. Things like getting customers and invoices, updating and saving etc.
|
|
17
17
|
* Some advanced features implemented, for instance support for multiple Access Tokens and filtering entities.
|
|
18
18
|
* We have ideas for more advanced features, like sorting entities, pagination of results but nothing in the pipeline right now.
|
|
19
19
|
* A few models implemented. Right now we pretty good support for `Customer`, `Invoice`, `Order`, `Article`, `Label` and `Project`. Adding more models in general is quick and easy (that's the whole point with this gem), see the developer guide further down.
|
|
20
|
-
* Massive refactorings no longer occurs weekly :)
|
|
21
20
|
|
|
22
21
|
# Architecture overview
|
|
23
22
|
The gem is structured with distinct models for the tasks of data, JSON mapping and saving state. These are called: model, type, mapper and repository.
|
|
@@ -81,7 +80,7 @@ These are responsible for the mapping between our plain old Ruby object models a
|
|
|
81
80
|
|
|
82
81
|
# Requirements
|
|
83
82
|
|
|
84
|
-
This gem is
|
|
83
|
+
This gem is built for Ruby 2.5 or higher (see Travis configuration file for what versions we are testing against).
|
|
85
84
|
|
|
86
85
|
## Installation
|
|
87
86
|
|
|
@@ -191,5 +190,9 @@ updated_customer.name #=> "Ned Stark"
|
|
|
191
190
|
|
|
192
191
|
The update method takes an implicit hash of attributes to update, so you can update as many as you like in one go.
|
|
193
192
|
|
|
193
|
+
# Development
|
|
194
|
+
## Testing
|
|
195
|
+
This gem has integration tests to verify the code against the real API. It uses [vcr](https://github.com/vcr/vcr) to record API endpoint responses. These responses are stored locally and are called vcr cassettes. If no cassettes are available, vcr will record new ones for you. Once in a while, it's good to throw away all cassettes and rerecord them. Fortnox updates their endpoints and we need to keep our code up to date with the reality. There's a handy rake task for removing all cassettes, see `rake -T`. Note that when rerecording all cassettes, do it one repository at a time, otherwise you'll definitely get `429 Too Many Requests` from Fortnox. Run them manually with something like `bundle exec rspec spec/fortnox/api/repositories/article_spec.rb`. Also, you will need to update some test data in specs, see notes in specs.
|
|
196
|
+
|
|
194
197
|
# Contributing
|
|
195
198
|
See the [CONTRIBUTE](CONTRIBUTE.md) readme.
|
data/Rakefile
CHANGED
data/fortnox-api.gemspec
CHANGED
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
|
23
23
|
spec.test_files = spec.files.grep(%r{^(spec)/})
|
|
24
24
|
spec.require_paths = ['lib']
|
|
25
25
|
|
|
26
|
-
spec.required_ruby_version = '>= 2.
|
|
26
|
+
spec.required_ruby_version = '>= 2.5'
|
|
27
27
|
spec.add_dependency 'countries', '~> 3.0'
|
|
28
28
|
spec.add_dependency 'dry-struct', '~> 0.1'
|
|
29
29
|
spec.add_dependency 'dry-types', '~> 0.8', '< 0.13.0'
|
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
|
33
33
|
spec.add_development_dependency 'guard', '~> 2.12'
|
|
34
34
|
spec.add_development_dependency 'guard-rspec', '~> 4.5'
|
|
35
35
|
spec.add_development_dependency 'pry', '~> 0'
|
|
36
|
-
spec.add_development_dependency 'rake', '
|
|
36
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.2'
|
|
38
38
|
spec.add_development_dependency 'rspec-collection_matchers', '~> 0'
|
|
39
39
|
spec.add_development_dependency 'rubocop', '~> 0.52.0'
|
|
@@ -72,8 +72,8 @@ module Fortnox
|
|
|
72
72
|
|
|
73
73
|
def default_key_from_json_transform(key)
|
|
74
74
|
key = key.to_s
|
|
75
|
-
key = camelcase_to_underscore(key) unless key
|
|
76
|
-
key = strip_at_symbol(key) if key
|
|
75
|
+
key = camelcase_to_underscore(key) unless key.match?(/\A[A-Z]+\z/)
|
|
76
|
+
key = strip_at_symbol(key) if key.match?(/\A@.*\z/)
|
|
77
77
|
key.downcase.to_sym
|
|
78
78
|
end
|
|
79
79
|
|
|
@@ -154,6 +154,9 @@ module Fortnox
|
|
|
154
154
|
# TaxReduction The amount of tax reduction.
|
|
155
155
|
attribute :tax_reduction, Types::Nullable::Integer.is(:read_only)
|
|
156
156
|
|
|
157
|
+
# TaxReductionType Tax Reduction Type
|
|
158
|
+
attribute :tax_reduction_type, Types::TaxReductionType
|
|
159
|
+
|
|
157
160
|
# TermsOfDelivery Code of the terms of delivery.
|
|
158
161
|
attribute :terms_of_delivery, Types::Nullable::String
|
|
159
162
|
|
data/lib/fortnox/api/types.rb
CHANGED
|
@@ -57,7 +57,7 @@ module Fortnox
|
|
|
57
57
|
next value if value.nil? || value == ''
|
|
58
58
|
|
|
59
59
|
# Fortnox only supports Swedish translation of Sweden
|
|
60
|
-
next CountryString.new('SE') if value
|
|
60
|
+
next CountryString.new('SE') if value.match?(/^s(e$|we|ve)/i)
|
|
61
61
|
|
|
62
62
|
country = ::ISO3166::Country[value] ||
|
|
63
63
|
::ISO3166::Country.find_country_by_name(value) ||
|
|
@@ -119,6 +119,11 @@ module Fortnox
|
|
|
119
119
|
.optional
|
|
120
120
|
.constructor(EnumConstructors.default)
|
|
121
121
|
|
|
122
|
+
TaxReductionType = Strict::String
|
|
123
|
+
.constrained(included_in: TaxReductionTypes.values)
|
|
124
|
+
.optional
|
|
125
|
+
.constructor(EnumConstructors.lower_case)
|
|
126
|
+
|
|
122
127
|
require 'fortnox/api/types/model'
|
|
123
128
|
require 'fortnox/api/types/default_delivery_types'
|
|
124
129
|
require 'fortnox/api/types/default_templates'
|
|
@@ -17,6 +17,13 @@ module Fortnox
|
|
|
17
17
|
value.to_s.upcase unless value.nil?
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
def self.lower_case
|
|
22
|
+
lambda do |value|
|
|
23
|
+
return nil if value == ''
|
|
24
|
+
value.to_s.downcase unless value.nil?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
20
27
|
end
|
|
21
28
|
|
|
22
29
|
ArticleTypes = Types::Strict::String.enum(
|
|
@@ -25,15 +32,31 @@ module Fortnox
|
|
|
25
32
|
DiscountTypes = Types::Strict::String.enum(
|
|
26
33
|
'AMOUNT', 'PERCENT'
|
|
27
34
|
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
HOUSEWORK_TYPES = {
|
|
36
|
+
rot: %w[
|
|
37
|
+
CONSTRUCTION ELECTRICITY GLASSMETALWORK GROUNDDRAINAGEWORK
|
|
38
|
+
MASONRY PAINTINGWALLPAPERING HVAC OTHERCOSTS
|
|
39
|
+
],
|
|
40
|
+
rut: %w[
|
|
41
|
+
MAJORAPPLIANCEREPAIR MOVINGSERVICES ITSERVICES CLEANING
|
|
42
|
+
TEXTILECLOTHING SNOWPLOWING GARDENING BABYSITTING OTHERCARE
|
|
43
|
+
OTHERCOSTS
|
|
44
|
+
],
|
|
45
|
+
legacy_rut: %w[COOKING TUTORING]
|
|
46
|
+
}.freeze
|
|
47
|
+
|
|
48
|
+
# TODO: RUT to be added:
|
|
49
|
+
# HOMEMAINTENANCE FURNISHING TRANSPORTATIONSERVICES
|
|
50
|
+
# WASHINGANDCAREOFCLOTHING
|
|
51
|
+
#
|
|
52
|
+
# TODO: GREEN to be added:
|
|
53
|
+
# SOLARCELLS STORAGESELFPRODUCEDELECTRICTY
|
|
54
|
+
# CHARGINGSTATIONELECTRICVEHICLE OTHERCOSTS
|
|
55
|
+
|
|
35
56
|
HouseworkTypes = Types::Strict::String.enum(
|
|
36
|
-
*(
|
|
57
|
+
*(HOUSEWORK_TYPES[:rot] +
|
|
58
|
+
HOUSEWORK_TYPES[:rut] +
|
|
59
|
+
HOUSEWORK_TYPES[:legacy_rut]).uniq
|
|
37
60
|
)
|
|
38
61
|
Currencies = Types::Strict::String.enum(
|
|
39
62
|
'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN',
|
|
@@ -67,6 +90,11 @@ module Fortnox
|
|
|
67
90
|
ProjectStatusTypes = Types::Strict::String.enum(
|
|
68
91
|
'NOTSTARTED', 'ONGOING', 'COMPLETED'
|
|
69
92
|
)
|
|
93
|
+
# NOTE: Yes, these needs to be in lower case...
|
|
94
|
+
# I know, this is stupid... Fortnox: why?!
|
|
95
|
+
TaxReductionTypes = Types::Strict::String.enum(
|
|
96
|
+
'rot', 'rut', 'green', 'none'
|
|
97
|
+
)
|
|
70
98
|
end
|
|
71
99
|
end
|
|
72
100
|
end
|
data/lib/fortnox/api/version.rb
CHANGED
|
@@ -6,11 +6,11 @@ require 'fortnox/api/circular_queue'
|
|
|
6
6
|
describe Fortnox::API::CircularQueue do
|
|
7
7
|
describe 'start index' do
|
|
8
8
|
context 'when running several times' do
|
|
9
|
+
subject { Set.new(samples).size }
|
|
10
|
+
|
|
9
11
|
let(:test_array) { (0..99).to_a }
|
|
10
12
|
let(:samples) { Array.new(100) { described_class.new(*test_array).next } }
|
|
11
13
|
|
|
12
|
-
subject { Set.new(samples).size }
|
|
13
|
-
|
|
14
14
|
# NOTE: This test is not perfect. We are testing that a random generator
|
|
15
15
|
# with 100 items to choose from does not choose the same item 100 times in a row.
|
|
16
16
|
# Yes, the possibility is low, but I thought I should just mention it :)
|
|
@@ -22,7 +22,7 @@ describe Fortnox::API::CircularQueue do
|
|
|
22
22
|
|
|
23
23
|
describe '#next' do
|
|
24
24
|
context 'when several items in queue' do
|
|
25
|
-
let(:queue) { described_class.new(1,2,3) }
|
|
25
|
+
let(:queue) { described_class.new(1, 2, 3) }
|
|
26
26
|
let(:first_round) { Array.new(3) { queue.next } }
|
|
27
27
|
let(:second_round) { Array.new(3) { queue.next } }
|
|
28
28
|
|
|
@@ -27,7 +27,7 @@ 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', 29
|
|
31
31
|
|
|
32
32
|
# When recording new VCR cassettes, expected matches must be increased
|
|
33
33
|
include_examples '.find', '1' do
|
|
@@ -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', 31
|
|
43
43
|
|
|
44
44
|
describe 'country reference' do
|
|
45
45
|
describe 'with valid country code \'SE\'' do
|
|
@@ -37,7 +37,7 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
|
|
|
37
37
|
|
|
38
38
|
# It is not possible to delete Invoces. Therefore, expected nr of Orders
|
|
39
39
|
# when running .all will continue to increase (until 100, which is max by default).
|
|
40
|
-
include_examples '.all',
|
|
40
|
+
include_examples '.all', 100
|
|
41
41
|
|
|
42
42
|
include_examples '.find', 1 do
|
|
43
43
|
let(:find_by_hash_failure) { { yourreference: 'Not found' } }
|
|
@@ -129,27 +129,27 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
|
|
|
129
129
|
|
|
130
130
|
before { persisted_invoice }
|
|
131
131
|
|
|
132
|
-
context '
|
|
132
|
+
context 'when setting value to nil' do
|
|
133
|
+
subject { updated_persisted_invoice.comments }
|
|
134
|
+
|
|
133
135
|
let(:updated_persisted_invoice) do
|
|
134
136
|
VCR.use_cassette("#{vcr_dir}/save_old_with_nil_comments") do
|
|
135
137
|
repository.save(persisted_invoice.update(comments: nil))
|
|
136
138
|
end
|
|
137
139
|
end
|
|
138
140
|
|
|
139
|
-
subject { updated_persisted_invoice.comments }
|
|
140
|
-
|
|
141
141
|
pending { is_expected.to eq(nil) }
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
context '
|
|
144
|
+
context 'when setting value to empty string' do
|
|
145
|
+
subject { updated_persisted_invoice.comments }
|
|
146
|
+
|
|
145
147
|
let(:updated_persisted_invoice) do
|
|
146
148
|
VCR.use_cassette("#{vcr_dir}/save_old_with_empty_comments") do
|
|
147
149
|
repository.save(persisted_invoice.update(comments: ''))
|
|
148
150
|
end
|
|
149
151
|
end
|
|
150
152
|
|
|
151
|
-
subject { updated_persisted_invoice.comments }
|
|
152
|
-
|
|
153
153
|
it 'does not reset the value' do
|
|
154
154
|
is_expected.to eq('A comment to be reset')
|
|
155
155
|
end
|
|
@@ -169,7 +169,9 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
|
|
|
169
169
|
|
|
170
170
|
before { persisted_invoice }
|
|
171
171
|
|
|
172
|
-
context '
|
|
172
|
+
context 'when setting value to nil' do
|
|
173
|
+
subject { updated_persisted_invoice.country }
|
|
174
|
+
|
|
173
175
|
let(:updated_persisted_invoice) do
|
|
174
176
|
# TODO: This VCR cassette needs to be re-recorded again
|
|
175
177
|
# when the we fix #172.
|
|
@@ -178,20 +180,18 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
|
|
|
178
180
|
end
|
|
179
181
|
end
|
|
180
182
|
|
|
181
|
-
subject { updated_persisted_invoice.country }
|
|
182
|
-
|
|
183
183
|
pending { is_expected.to eq(nil) }
|
|
184
184
|
end
|
|
185
185
|
|
|
186
|
-
context '
|
|
186
|
+
context 'when setting value to empty string' do
|
|
187
|
+
subject { updated_persisted_invoice.country }
|
|
188
|
+
|
|
187
189
|
let(:updated_persisted_invoice) do
|
|
188
190
|
VCR.use_cassette("#{vcr_dir}/save_old_with_empty_country") do
|
|
189
191
|
repository.save(persisted_invoice.update(country: ''))
|
|
190
192
|
end
|
|
191
193
|
end
|
|
192
194
|
|
|
193
|
-
subject { updated_persisted_invoice.country }
|
|
194
|
-
|
|
195
195
|
it 'does not reset the country' do
|
|
196
196
|
is_expected.to eq('SE')
|
|
197
197
|
end
|
|
@@ -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', 33
|
|
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: '19DAYS' }
|
|
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', 13
|
|
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: 'blarg5' }
|
|
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
|
+
'woooh5'
|
|
29
29
|
|
|
30
30
|
# When recording new VCR cassettes, expected number must be updated
|
|
31
|
-
include_examples '.all',
|
|
31
|
+
include_examples '.all', 14
|
|
32
32
|
|
|
33
33
|
include_examples '.find', 'blarg', find_by_hash: false do
|
|
34
34
|
let(:find_by_hash_failure) { { code: 'notfound' } }
|
|
@@ -13,4 +13,5 @@ describe Fortnox::API::Types do
|
|
|
13
13
|
it_behaves_like 'enum', 'VATType', 'VATTypes'
|
|
14
14
|
it_behaves_like 'enum', 'DefaultDeliveryType', 'DefaultDeliveryTypeValues'
|
|
15
15
|
it_behaves_like 'enum', 'ProjectStatusType', 'ProjectStatusTypes'
|
|
16
|
+
it_behaves_like 'enum', 'TaxReductionType', 'TaxReductionTypes'
|
|
16
17
|
end
|
|
@@ -14,29 +14,32 @@ describe 'HouseworkTypes', integration: true do
|
|
|
14
14
|
before { set_api_test_configuration }
|
|
15
15
|
|
|
16
16
|
let(:repository) { Fortnox::API::Repository::Order.new }
|
|
17
|
-
let(:valid_model) do
|
|
18
|
-
Fortnox::API::Model::Order.new(customer_number: '1', order_rows: [order_row])
|
|
19
|
-
end
|
|
20
|
-
let(:order_row) do
|
|
21
|
-
Fortnox::API::Types::OrderRow.new(ordered_quantity: 1,
|
|
22
|
-
article_number: '0000',
|
|
23
|
-
housework_type: housework_type)
|
|
24
|
-
end
|
|
25
17
|
|
|
26
|
-
shared_examples_for 'housework type' do |type, legacy: false|
|
|
18
|
+
shared_examples_for 'housework type' do |type, tax_reduction_type, legacy: false, housework: true|
|
|
27
19
|
subject do
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
repository.save(valid_model)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
20
|
+
cassette = "orders/housework_type_#{type.downcase}"
|
|
21
|
+
-> { VCR.use_cassette(cassette) { repository.save(document) } }
|
|
33
22
|
end
|
|
34
23
|
|
|
35
|
-
let(:
|
|
36
|
-
|
|
24
|
+
let(:document) do
|
|
25
|
+
Fortnox::API::Model::Order.new(
|
|
26
|
+
customer_number: '1',
|
|
27
|
+
tax_reduction_type: tax_reduction_type,
|
|
28
|
+
order_rows: [
|
|
29
|
+
Fortnox::API::Types::OrderRow.new(
|
|
30
|
+
ordered_quantity: 1,
|
|
31
|
+
article_number: '0000',
|
|
32
|
+
housework_type: Fortnox::API::Types::HouseworkTypes[type],
|
|
33
|
+
housework: housework
|
|
34
|
+
)
|
|
35
|
+
]
|
|
36
|
+
)
|
|
37
|
+
end
|
|
37
38
|
|
|
38
39
|
context "when creating an OrderRow with housework_type set to #{type}" do
|
|
39
40
|
if legacy
|
|
41
|
+
let(:error_message) { 'Skattereduktion för den valda typen av husarbete har upphört.' }
|
|
42
|
+
|
|
40
43
|
it 'raises an error' do
|
|
41
44
|
is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
|
|
42
45
|
end
|
|
@@ -46,23 +49,137 @@ describe 'HouseworkTypes', integration: true do
|
|
|
46
49
|
end
|
|
47
50
|
end
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
it_behaves_like 'housework type', '
|
|
53
|
-
it_behaves_like 'housework type', '
|
|
54
|
-
it_behaves_like 'housework type', '
|
|
55
|
-
it_behaves_like 'housework type', '
|
|
56
|
-
it_behaves_like 'housework type', '
|
|
57
|
-
it_behaves_like 'housework type', '
|
|
58
|
-
it_behaves_like 'housework type', '
|
|
59
|
-
it_behaves_like 'housework type', '
|
|
60
|
-
|
|
61
|
-
it_behaves_like 'housework type', '
|
|
62
|
-
it_behaves_like 'housework type', '
|
|
63
|
-
it_behaves_like 'housework type', '
|
|
64
|
-
|
|
65
|
-
it_behaves_like 'housework type', '
|
|
66
|
-
it_behaves_like 'housework type', '
|
|
52
|
+
TYPE_ROT = Fortnox::API::Types::TaxReductionTypes['rot']
|
|
53
|
+
TYPE_RUT = Fortnox::API::Types::TaxReductionTypes['rut']
|
|
54
|
+
|
|
55
|
+
it_behaves_like 'housework type', 'CONSTRUCTION', TYPE_ROT
|
|
56
|
+
it_behaves_like 'housework type', 'ELECTRICITY', TYPE_ROT
|
|
57
|
+
it_behaves_like 'housework type', 'GLASSMETALWORK', TYPE_ROT
|
|
58
|
+
it_behaves_like 'housework type', 'GROUNDDRAINAGEWORK', TYPE_ROT
|
|
59
|
+
it_behaves_like 'housework type', 'MASONRY', TYPE_ROT
|
|
60
|
+
it_behaves_like 'housework type', 'PAINTINGWALLPAPERING', TYPE_ROT
|
|
61
|
+
it_behaves_like 'housework type', 'HVAC', TYPE_ROT
|
|
62
|
+
it_behaves_like 'housework type', 'OTHERCOSTS', TYPE_ROT, housework: false
|
|
63
|
+
|
|
64
|
+
it_behaves_like 'housework type', 'MAJORAPPLIANCEREPAIR', TYPE_RUT
|
|
65
|
+
it_behaves_like 'housework type', 'MOVINGSERVICES', TYPE_RUT
|
|
66
|
+
it_behaves_like 'housework type', 'ITSERVICES', TYPE_RUT
|
|
67
|
+
it_behaves_like 'housework type', 'CLEANING', TYPE_RUT
|
|
68
|
+
it_behaves_like 'housework type', 'TEXTILECLOTHING', TYPE_RUT
|
|
69
|
+
it_behaves_like 'housework type', 'SNOWPLOWING', TYPE_RUT
|
|
70
|
+
it_behaves_like 'housework type', 'GARDENING', TYPE_RUT
|
|
71
|
+
it_behaves_like 'housework type', 'BABYSITTING', TYPE_RUT
|
|
72
|
+
it_behaves_like 'housework type', 'OTHERCARE', TYPE_RUT
|
|
73
|
+
it_behaves_like 'housework type', 'OTHERCOSTS', TYPE_RUT, housework: false
|
|
74
|
+
|
|
75
|
+
# rubocop:disable RSpec/RepeatedDescription
|
|
76
|
+
pending 'to be added' do
|
|
77
|
+
raise Exception, 'Will be supported 2021-01-01'
|
|
78
|
+
# it_behaves_like 'housework type', 'HOMEMAINTENANCE', TYPE_RUT
|
|
79
|
+
# it_behaves_like 'housework type', 'FURNISHING', TYPE_RUT
|
|
80
|
+
# it_behaves_like 'housework type', 'TRANSPORTATIONSERVICES', TYPE_RUT
|
|
81
|
+
# it_behaves_like 'housework type', 'WASHINGANDCAREOFCLOTHING', TYPE_RUT
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
pending 'to be added' do
|
|
85
|
+
raise Exception, 'Will be supported 2021-01-01'
|
|
86
|
+
# it_behaves_like 'housework type', 'SOLARCELLS', TYPE_GREEN
|
|
87
|
+
# it_behaves_like 'housework type', 'STORAGESELFPRODUCEDELECTRICTY', TYPE_GREEN
|
|
88
|
+
# it_behaves_like 'housework type', 'CHARGINGSTATIONELECTRICVEHICLE', TYPE_GREEN
|
|
89
|
+
# it_behaves_like 'housework type', 'OTHERCOSTS', TYPE_GREEN
|
|
90
|
+
end
|
|
91
|
+
# rubocop:enable RSpec/RepeatedDescription
|
|
92
|
+
|
|
93
|
+
it_behaves_like 'housework type', 'COOKING', TYPE_RUT, legacy: true
|
|
94
|
+
it_behaves_like 'housework type', 'TUTORING', TYPE_RUT, legacy: true
|
|
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
|
+
describe 'with OTHERCOSTS' do
|
|
126
|
+
subject do
|
|
127
|
+
cassette = 'orders/housework_othercoses_invalid'
|
|
128
|
+
-> { VCR.use_cassette(cassette) { repository.save(document) } }
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
let(:document) do
|
|
132
|
+
Fortnox::API::Model::Order.new(
|
|
133
|
+
customer_number: '1',
|
|
134
|
+
tax_reduction_type: TYPE_ROT,
|
|
135
|
+
order_rows: [
|
|
136
|
+
Fortnox::API::Types::OrderRow.new(
|
|
137
|
+
ordered_quantity: 1,
|
|
138
|
+
article_number: '0000',
|
|
139
|
+
housework_type: Fortnox::API::Types::HouseworkTypes['OTHERCOSTS'],
|
|
140
|
+
housework: true
|
|
141
|
+
)
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
let(:error_message) { 'Kan inte sätta typen övrig kostnad på en rad markerad som husarbete.' }
|
|
147
|
+
|
|
148
|
+
it "can't have housework set to true" do
|
|
149
|
+
is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
describe 'with wrong tax reduction type' do
|
|
154
|
+
subject do
|
|
155
|
+
cassette = 'orders/housework_invalid_tax_reduction_type'
|
|
156
|
+
-> { VCR.use_cassette(cassette) { repository.save(document) } }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
let(:type) { 'CONSTRUCTION' }
|
|
160
|
+
let(:document) do
|
|
161
|
+
Fortnox::API::Model::Order.new(
|
|
162
|
+
customer_number: '1',
|
|
163
|
+
tax_reduction_type: TYPE_RUT,
|
|
164
|
+
order_rows: [
|
|
165
|
+
Fortnox::API::Types::OrderRow.new(
|
|
166
|
+
ordered_quantity: 1,
|
|
167
|
+
article_number: '0000',
|
|
168
|
+
housework_type: Fortnox::API::Types::HouseworkTypes[type],
|
|
169
|
+
housework: true
|
|
170
|
+
)
|
|
171
|
+
]
|
|
172
|
+
)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
let(:error_message) do
|
|
176
|
+
"Dokument med skattereduktionstypen '#{TYPE_RUT}' " \
|
|
177
|
+
"får inte innehålla rader med husarbetestypen '#{type}'."
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it 'raises an error' do
|
|
181
|
+
is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
67
184
|
end
|
|
68
185
|
# rubocop:enable RSpec/DescribeClass
|