fortnox-api 0.7.2 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/.tool-versions +1 -0
  5. data/.travis.yml +5 -10
  6. data/CHANGELOG.md +45 -1
  7. data/README.md +7 -4
  8. data/Rakefile +5 -0
  9. data/fortnox-api.gemspec +22 -17
  10. data/lib/fortnox/api/mappers/article.rb +1 -1
  11. data/lib/fortnox/api/mappers/base/from_json.rb +3 -3
  12. data/lib/fortnox/api/mappers/base/to_json.rb +2 -2
  13. data/lib/fortnox/api/mappers/base.rb +3 -3
  14. data/lib/fortnox/api/mappers/customer.rb +1 -1
  15. data/lib/fortnox/api/mappers/default_delivery_types.rb +1 -1
  16. data/lib/fortnox/api/mappers/default_templates.rb +1 -1
  17. data/lib/fortnox/api/mappers/edi_information.rb +1 -1
  18. data/lib/fortnox/api/mappers/email_information.rb +1 -1
  19. data/lib/fortnox/api/mappers/invoice.rb +4 -4
  20. data/lib/fortnox/api/mappers/invoice_row.rb +1 -1
  21. data/lib/fortnox/api/mappers/order.rb +4 -4
  22. data/lib/fortnox/api/mappers/order_row.rb +1 -1
  23. data/lib/fortnox/api/mappers/project.rb +1 -1
  24. data/lib/fortnox/api/mappers/terms_of_payment.rb +1 -1
  25. data/lib/fortnox/api/mappers/unit.rb +1 -1
  26. data/lib/fortnox/api/mappers/value/country_string.rb +1 -1
  27. data/lib/fortnox/api/mappers.rb +18 -18
  28. data/lib/fortnox/api/models/article.rb +2 -2
  29. data/lib/fortnox/api/models/base.rb +14 -14
  30. data/lib/fortnox/api/models/customer.rb +2 -2
  31. data/lib/fortnox/api/models/document.rb +5 -2
  32. data/lib/fortnox/api/models/invoice.rb +2 -2
  33. data/lib/fortnox/api/models/label.rb +1 -1
  34. data/lib/fortnox/api/models/order.rb +2 -2
  35. data/lib/fortnox/api/models/project.rb +2 -2
  36. data/lib/fortnox/api/models/terms_of_payment.rb +2 -2
  37. data/lib/fortnox/api/models/unit.rb +2 -2
  38. data/lib/fortnox/api/models.rb +7 -7
  39. data/lib/fortnox/api/repositories/article.rb +3 -3
  40. data/lib/fortnox/api/repositories/base.rb +4 -3
  41. data/lib/fortnox/api/repositories/customer.rb +3 -3
  42. data/lib/fortnox/api/repositories/invoice.rb +3 -3
  43. data/lib/fortnox/api/repositories/order.rb +3 -3
  44. data/lib/fortnox/api/repositories/project.rb +3 -3
  45. data/lib/fortnox/api/repositories/terms_of_payment.rb +3 -3
  46. data/lib/fortnox/api/repositories/unit.rb +3 -3
  47. data/lib/fortnox/api/repositories.rb +7 -7
  48. data/lib/fortnox/api/types/default_delivery_types.rb +0 -2
  49. data/lib/fortnox/api/types/default_templates.rb +0 -2
  50. data/lib/fortnox/api/types/edi_information.rb +0 -2
  51. data/lib/fortnox/api/types/email_information.rb +0 -2
  52. data/lib/fortnox/api/types/enums.rb +36 -8
  53. data/lib/fortnox/api/types/invoice_row.rb +1 -1
  54. data/lib/fortnox/api/types/model.rb +4 -6
  55. data/lib/fortnox/api/types/nullable.rb +13 -9
  56. data/lib/fortnox/api/types/order_row.rb +1 -1
  57. data/lib/fortnox/api/types/required.rb +3 -3
  58. data/lib/fortnox/api/types/sized.rb +2 -2
  59. data/lib/fortnox/api/types.rb +23 -23
  60. data/lib/fortnox/api/version.rb +1 -1
  61. data/lib/fortnox/api.rb +18 -16
  62. data/spec/fortnox/api/circular_queue_spec.rb +3 -3
  63. data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +9 -7
  64. data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +1 -1
  65. data/spec/fortnox/api/mappers/examples/mapper.rb +1 -1
  66. data/spec/fortnox/api/models/base_spec.rb +8 -8
  67. data/spec/fortnox/api/repositories/article_spec.rb +2 -2
  68. data/spec/fortnox/api/repositories/base_spec.rb +4 -12
  69. data/spec/fortnox/api/repositories/customer_spec.rb +1 -1
  70. data/spec/fortnox/api/repositories/invoice_spec.rb +13 -19
  71. data/spec/fortnox/api/repositories/project_spec.rb +1 -1
  72. data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +2 -2
  73. data/spec/fortnox/api/repositories/unit_spec.rb +3 -3
  74. data/spec/fortnox/api/types/enums_spec.rb +1 -0
  75. data/spec/fortnox/api/types/housework_types_spec.rb +122 -34
  76. data/spec/fortnox/api/types/model_spec.rb +11 -17
  77. data/spec/fortnox/api/types/nullable_spec.rb +30 -10
  78. data/spec/fortnox/api/types/required_spec.rb +1 -4
  79. data/spec/support/matchers/type/enum_matcher.rb +1 -1
  80. data/spec/support/matchers/type/have_account_number_matcher.rb +1 -1
  81. data/spec/support/matchers/type/have_email_matcher.rb +1 -1
  82. data/spec/support/matchers/type/have_nullable_date_matcher.rb +5 -5
  83. data/spec/support/matchers/type/have_nullable_string_matcher.rb +3 -3
  84. data/spec/vcr_cassettes/articles/all.yml +43 -17
  85. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +34 -15
  86. data/spec/vcr_cassettes/articles/find_failure.yml +34 -15
  87. data/spec/vcr_cassettes/articles/find_id_1.yml +35 -16
  88. data/spec/vcr_cassettes/articles/find_new.yml +37 -18
  89. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +34 -15
  90. data/spec/vcr_cassettes/articles/save_new.yml +35 -15
  91. data/spec/vcr_cassettes/articles/save_old.yml +37 -18
  92. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +35 -15
  93. data/spec/vcr_cassettes/articles/search_by_name.yml +34 -15
  94. data/spec/vcr_cassettes/articles/search_miss.yml +34 -15
  95. data/spec/vcr_cassettes/articles/search_with_special_char.yml +34 -15
  96. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +38 -18
  97. data/spec/vcr_cassettes/customers/all.yml +36 -17
  98. data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +34 -15
  99. data/spec/vcr_cassettes/customers/find_failure.yml +34 -15
  100. data/spec/vcr_cassettes/customers/find_id_1.yml +34 -15
  101. data/spec/vcr_cassettes/customers/find_new.yml +36 -17
  102. data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +34 -15
  103. data/spec/vcr_cassettes/customers/save_new.yml +34 -14
  104. data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +30 -20
  105. data/spec/vcr_cassettes/customers/save_old.yml +36 -17
  106. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +34 -14
  107. data/spec/vcr_cassettes/customers/search_by_name.yml +38 -16
  108. data/spec/vcr_cassettes/customers/search_miss.yml +34 -15
  109. data/spec/vcr_cassettes/customers/search_with_special_char.yml +34 -15
  110. data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +34 -15
  111. data/spec/vcr_cassettes/invoices/all.yml +39 -17
  112. data/spec/vcr_cassettes/invoices/filter_hit.yml +34 -15
  113. data/spec/vcr_cassettes/invoices/filter_invalid.yml +33 -13
  114. data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +34 -15
  115. data/spec/vcr_cassettes/invoices/find_failure.yml +34 -15
  116. data/spec/vcr_cassettes/invoices/find_id_1.yml +36 -17
  117. data/spec/vcr_cassettes/invoices/find_new.yml +39 -20
  118. data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +34 -15
  119. data/spec/vcr_cassettes/invoices/save_new.yml +37 -17
  120. data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +37 -17
  121. data/spec/vcr_cassettes/invoices/save_new_with_country.yml +32 -22
  122. data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +33 -23
  123. data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +32 -22
  124. data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +32 -22
  125. data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +32 -22
  126. data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +33 -23
  127. data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +33 -23
  128. data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +32 -22
  129. data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +32 -22
  130. data/spec/vcr_cassettes/invoices/save_old.yml +39 -20
  131. data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +39 -20
  132. data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +34 -25
  133. data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +39 -20
  134. data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +34 -25
  135. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +36 -16
  136. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +36 -16
  137. data/spec/vcr_cassettes/invoices/search_by_name.yml +34 -15
  138. data/spec/vcr_cassettes/invoices/search_miss.yml +34 -15
  139. data/spec/vcr_cassettes/invoices/search_with_special_char.yml +34 -15
  140. data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +34 -15
  141. data/spec/vcr_cassettes/orders/all.yml +35 -16
  142. data/spec/vcr_cassettes/orders/filter_hit.yml +34 -15
  143. data/spec/vcr_cassettes/orders/filter_invalid.yml +33 -13
  144. data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +34 -15
  145. data/spec/vcr_cassettes/orders/find_failure.yml +34 -15
  146. data/spec/vcr_cassettes/orders/find_id_1.yml +35 -16
  147. data/spec/vcr_cassettes/orders/find_new.yml +38 -19
  148. data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +63 -0
  149. data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +63 -0
  150. data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +37 -17
  151. data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +37 -17
  152. data/spec/vcr_cassettes/orders/housework_type_construction.yml +37 -17
  153. data/spec/vcr_cassettes/orders/housework_type_cooking.yml +34 -14
  154. data/spec/vcr_cassettes/orders/housework_type_electricity.yml +37 -17
  155. data/spec/vcr_cassettes/orders/housework_type_gardening.yml +37 -17
  156. data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +37 -17
  157. data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +37 -17
  158. data/spec/vcr_cassettes/orders/housework_type_hvac.yml +37 -17
  159. data/spec/vcr_cassettes/orders/housework_type_itservices.yml +66 -0
  160. data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +66 -0
  161. data/spec/vcr_cassettes/orders/housework_type_masonry.yml +37 -17
  162. data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +66 -0
  163. data/spec/vcr_cassettes/orders/housework_type_othercare.yml +37 -17
  164. data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +37 -17
  165. data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +37 -17
  166. data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +37 -17
  167. data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +37 -17
  168. data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +34 -14
  169. data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +34 -15
  170. data/spec/vcr_cassettes/orders/save_new.yml +36 -16
  171. data/spec/vcr_cassettes/orders/save_old.yml +38 -19
  172. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +36 -16
  173. data/spec/vcr_cassettes/orders/search_by_name.yml +34 -15
  174. data/spec/vcr_cassettes/orders/search_miss.yml +34 -15
  175. data/spec/vcr_cassettes/orders/search_with_special_char.yml +34 -15
  176. data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +34 -15
  177. data/spec/vcr_cassettes/projects/all.yml +58 -33
  178. data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +34 -15
  179. data/spec/vcr_cassettes/projects/find_failure.yml +34 -15
  180. data/spec/vcr_cassettes/projects/find_id_1.yml +34 -15
  181. data/spec/vcr_cassettes/projects/find_new.yml +37 -18
  182. data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +36 -17
  183. data/spec/vcr_cassettes/projects/save_new.yml +35 -15
  184. data/spec/vcr_cassettes/projects/save_old.yml +37 -18
  185. data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +36 -17
  186. data/spec/vcr_cassettes/termsofpayments/all.yml +46 -25
  187. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +34 -15
  188. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +35 -16
  189. data/spec/vcr_cassettes/termsofpayments/find_new.yml +36 -17
  190. data/spec/vcr_cassettes/termsofpayments/save_new.yml +35 -15
  191. data/spec/vcr_cassettes/termsofpayments/save_old.yml +36 -17
  192. data/spec/vcr_cassettes/units/all.yml +45 -22
  193. data/spec/vcr_cassettes/units/find_failure.yml +34 -15
  194. data/spec/vcr_cassettes/units/find_id_1.yml +35 -16
  195. data/spec/vcr_cassettes/units/find_new.yml +36 -17
  196. data/spec/vcr_cassettes/units/save_new.yml +35 -15
  197. data/spec/vcr_cassettes/units/save_old.yml +36 -17
  198. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +35 -15
  199. metadata +115 -43
  200. data/spec/support/helpers/dummy_class_helper.rb +0 -38
  201. data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +0 -57
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/models/article'
4
- require 'fortnox/api/models/customer'
5
- require 'fortnox/api/models/invoice'
6
- require 'fortnox/api/models/order'
7
- require 'fortnox/api/models/project'
8
- require 'fortnox/api/models/unit'
9
- require 'fortnox/api/models/terms_of_payment'
3
+ require_relative 'models/article'
4
+ require_relative 'models/customer'
5
+ require_relative 'models/invoice'
6
+ require_relative 'models/order'
7
+ require_relative 'models/project'
8
+ require_relative 'models/unit'
9
+ require_relative 'models/terms_of_payment'
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/article'
5
- require 'fortnox/api/mappers/article'
3
+ require_relative 'base'
4
+ require_relative '../models/article'
5
+ require_relative '../mappers/article'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'httparty'
4
- require 'fortnox/api/request_handling'
5
- require 'fortnox/api/repositories/base/loaders'
6
- require 'fortnox/api/repositories/base/savers'
4
+
5
+ require_relative 'base/loaders'
6
+ require_relative 'base/savers'
7
+ require_relative '../request_handling'
7
8
 
8
9
  module Fortnox
9
10
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/customer'
5
- require 'fortnox/api/mappers/customer'
3
+ require_relative 'base'
4
+ require_relative '../models/customer'
5
+ require_relative '../mappers/customer'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/invoice'
5
- require 'fortnox/api/mappers/invoice'
3
+ require_relative 'base'
4
+ require_relative '../models/invoice'
5
+ require_relative '../mappers/invoice'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/order'
5
- require 'fortnox/api/mappers/order'
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
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/project'
5
- require 'fortnox/api/mappers/project'
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
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/terms_of_payment'
5
- require 'fortnox/api/mappers/terms_of_payment'
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
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/unit'
5
- require 'fortnox/api/mappers/unit'
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
- require 'fortnox/api/repositories/article'
4
- require 'fortnox/api/repositories/customer'
5
- require 'fortnox/api/repositories/invoice'
6
- require 'fortnox/api/repositories/order'
7
- require 'fortnox/api/repositories/project'
8
- require 'fortnox/api/repositories/unit'
9
- require 'fortnox/api/repositories/terms_of_payment'
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'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -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
- CURRENT_HOUSEWORK_TYPES = %w[
29
- CONSTRUCTION ELECTRICITY GLASSMETALWORK GROUNDDRAINAGEWORK
30
- MASONRY PAINTINGWALLPAPERING HVAC MAJORAPPLIANCEREPAIR
31
- MOVINGSERVICES ITSERVICES CLEANING TEXTILECLOTHING
32
- SNOWPLOWING GARDENING BABYSITTING OTHERCARE OTHERCOSTS
33
- ].freeze
34
- LEGACY_HOUSEWORK_TYPES = %w[COOKING TUTORING].freeze
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
- *(CURRENT_HOUSEWORK_TYPES + LEGACY_HOUSEWORK_TYPES)
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types/document_row'
3
+ require_relative 'document_row'
4
4
 
5
5
  module Fortnox
6
6
  module API
@@ -4,7 +4,7 @@ module Fortnox
4
4
  module API
5
5
  module Types
6
6
  class Model < Dry::Struct
7
- constructor_type(:schema)
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 = self.class.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[name]
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.to_s unless value.nil? }
10
- Float = Types::Strict::Float.optional.constructor { |value| value.to_f unless value.nil? }
11
- Integer = Types::Strict::Int.optional.constructor { |value| value.to_i unless value.nil? }
12
- Boolean = Types::Bool.optional.constructor { |value| THE_TRUTH.fetch(value) { false } }
13
- # TODO: Improve parsing!
14
- # In case date parsing fails, ArgumentError is thrown. Currently, it is rescued in Repository::Loaders.find.
15
- # That method assumes that the exception is due to invalid argument to the find method, which is not the case
16
- # if it is raised from here!
17
- Date = Types::Date.optional.constructor { |value| ::Date.parse(value.to_s) unless value.nil? || value == '' }
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types/document_row'
3
+ require_relative 'document_row'
4
4
 
5
5
  module Fortnox
6
6
  module API
@@ -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.to_s unless value.nil? }.is(:required)
8
- Integer = Types::Strict::Int.constructor { |value| value.to_i unless value.nil? }.is(:required)
9
- Float = Types::Strict::Float.constructor { |value| value.to_f unless value.nil? }.is(:required)
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::Int.constrained(gteq: low, lteq: high).optional.constructor do |value|
18
- value.to_i unless value.nil?
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
@@ -3,7 +3,7 @@
3
3
  require 'dry-struct'
4
4
  require 'dry-types'
5
5
  require 'countries'
6
- require 'fortnox/api/types/shim/country_string'
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::Types.module
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
- require 'fortnox/api/types/required'
34
- require 'fortnox/api/types/defaulted'
35
- require 'fortnox/api/types/nullable'
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
- require 'fortnox/api/types/sized'
33
+ require_relative 'types/enums'
34
+ require_relative 'types/sized'
40
35
 
41
- AccountNumber = Strict::Int
36
+ AccountNumber = Strict::Integer
42
37
  .constrained(gteq: 0, lteq: 9999)
43
38
  .optional
44
39
  .constructor do |value|
@@ -57,10 +52,10 @@ module Fortnox
57
52
  next value if value.nil? || value == ''
58
53
 
59
54
  # Fortnox only supports Swedish translation of Sweden
60
- next CountryString.new('SE') if value =~ /^s(e$|we|ve)/i
55
+ next CountryString.new('SE') if value.match?(/^s(e$|we|ve)/i)
61
56
 
62
57
  country = ::ISO3166::Country[value] ||
63
- ::ISO3166::Country.find_country_by_name(value) ||
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?
@@ -119,13 +114,18 @@ module Fortnox
119
114
  .optional
120
115
  .constructor(EnumConstructors.default)
121
116
 
122
- require 'fortnox/api/types/model'
123
- require 'fortnox/api/types/default_delivery_types'
124
- require 'fortnox/api/types/default_templates'
125
- require 'fortnox/api/types/email_information'
126
- require 'fortnox/api/types/edi_information'
127
- require 'fortnox/api/types/invoice_row'
128
- require 'fortnox/api/types/order_row'
117
+ TaxReductionType = Strict::String
118
+ .constrained(included_in: TaxReductionTypes.values)
119
+ .optional
120
+ .constructor(EnumConstructors.lower_case)
121
+
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'
129
129
  end
130
130
  end
131
131
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fortnox
4
4
  module API
5
- VERSION = '0.7.2'
5
+ VERSION = '0.8.1'
6
6
  end
7
7
  end
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-struct'
5
- require 'fortnox/api/circular_queue'
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(STDOUT)
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
- require 'fortnox/api/models'
79
- require 'fortnox/api/repositories'
80
- require 'fortnox/api/mappers'
80
+ require_relative 'api/models'
81
+ require_relative 'api/repositories'
82
+ require_relative 'api/mappers'
@@ -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
 
@@ -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
- using_test_class do
10
- class TestClass
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
- using_test_class do
22
- module Something
23
- class Test
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 { is_expected.to eq(key_map) }
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
- using_test_classes do
9
- class Entity < Fortnox::API::Model::Base
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 { Entity.new(string: 'Test') }
19
+ subject { entity_class.new(string: 'Test') }
20
20
 
21
- it { is_expected.to be_a Entity }
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 { -> { Entity.new({}) } }
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 { -> { Entity.new(string: 'Test', account: 13_337) } }
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) { Entity.new(string: 'Test') }
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 = Entity.new(string: 'Saved', new: false, unsaved: false)
88
+ saved_entity = entity_class.new(string: 'Saved', new: false, unsaved: false)
89
89
  saved_entity.update(string: 'Updated')
90
90
  end
91
91