fortnox-api 0.5.2 → 0.6.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.
Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +9 -1104
  4. data/.travis.yml +22 -2
  5. data/Gemfile +3 -1
  6. data/Guardfile +4 -2
  7. data/README.md +2 -2
  8. data/Rakefile +3 -1
  9. data/bin/console +17 -3
  10. data/fortnox-api.gemspec +32 -27
  11. data/lib/fortnox/api.rb +17 -16
  12. data/lib/fortnox/api/circular_queue.rb +13 -7
  13. data/lib/fortnox/api/mappers.rb +29 -25
  14. data/lib/fortnox/api/mappers/article.rb +7 -6
  15. data/lib/fortnox/api/mappers/base.rb +18 -16
  16. data/lib/fortnox/api/mappers/base/from_json.rb +37 -30
  17. data/lib/fortnox/api/mappers/base/to_json.rb +39 -37
  18. data/lib/fortnox/api/mappers/customer.rb +7 -7
  19. data/lib/fortnox/api/mappers/default_delivery_types.rb +4 -2
  20. data/lib/fortnox/api/mappers/default_templates.rb +5 -4
  21. data/lib/fortnox/api/mappers/edi_information.rb +5 -4
  22. data/lib/fortnox/api/mappers/email_information.rb +5 -4
  23. data/lib/fortnox/api/mappers/invoice.rb +10 -8
  24. data/lib/fortnox/api/mappers/invoice_row.rb +12 -7
  25. data/lib/fortnox/api/mappers/order.rb +10 -7
  26. data/lib/fortnox/api/mappers/order_row.rb +13 -6
  27. data/lib/fortnox/api/mappers/project.rb +6 -4
  28. data/lib/fortnox/api/mappers/terms_of_payments.rb +17 -0
  29. data/lib/fortnox/api/mappers/unit.rb +17 -0
  30. data/lib/fortnox/api/models.rb +9 -5
  31. data/lib/fortnox/api/models/article.rb +68 -67
  32. data/lib/fortnox/api/models/base.rb +52 -36
  33. data/lib/fortnox/api/models/customer.rb +95 -94
  34. data/lib/fortnox/api/models/document.rb +186 -0
  35. data/lib/fortnox/api/models/invoice.rb +44 -44
  36. data/lib/fortnox/api/models/label.rb +5 -3
  37. data/lib/fortnox/api/models/order.rb +8 -8
  38. data/lib/fortnox/api/models/project.rb +10 -8
  39. data/lib/fortnox/api/models/terms_of_payments.rb +28 -0
  40. data/lib/fortnox/api/models/unit.rb +24 -0
  41. data/lib/fortnox/api/repositories.rb +9 -5
  42. data/lib/fortnox/api/repositories/article.rb +6 -4
  43. data/lib/fortnox/api/repositories/base.rb +49 -46
  44. data/lib/fortnox/api/repositories/base/loaders.rb +32 -36
  45. data/lib/fortnox/api/repositories/base/savers.rb +23 -21
  46. data/lib/fortnox/api/repositories/customer.rb +6 -4
  47. data/lib/fortnox/api/repositories/invoice.rb +6 -4
  48. data/lib/fortnox/api/repositories/order.rb +6 -4
  49. data/lib/fortnox/api/repositories/project.rb +6 -4
  50. data/lib/fortnox/api/repositories/terms_of_payments.rb +17 -0
  51. data/lib/fortnox/api/repositories/unit.rb +17 -0
  52. data/lib/fortnox/api/request_handling.rb +12 -12
  53. data/lib/fortnox/api/types.rb +62 -11
  54. data/lib/fortnox/api/types/default_delivery_types.rb +5 -3
  55. data/lib/fortnox/api/types/default_templates.rb +3 -1
  56. data/lib/fortnox/api/types/defaulted.rb +2 -2
  57. data/lib/fortnox/api/types/document_row.rb +41 -42
  58. data/lib/fortnox/api/types/edi_information.rb +10 -8
  59. data/lib/fortnox/api/types/email_information.rb +10 -8
  60. data/lib/fortnox/api/types/enums.rb +60 -47
  61. data/lib/fortnox/api/types/invoice_row.rb +8 -8
  62. data/lib/fortnox/api/types/model.rb +14 -10
  63. data/lib/fortnox/api/types/nullable.rb +7 -7
  64. data/lib/fortnox/api/types/order_row.rb +5 -5
  65. data/lib/fortnox/api/types/required.rb +5 -5
  66. data/lib/fortnox/api/types/sized.rb +14 -6
  67. data/lib/fortnox/api/version.rb +3 -1
  68. data/spec/fortnox/api/mappers/article_spec.rb +3 -1
  69. data/spec/fortnox/api/mappers/base/from_json_spec.rb +15 -13
  70. data/spec/fortnox/api/mappers/base/to_json_spec.rb +4 -3
  71. data/spec/fortnox/api/mappers/base_spec.rb +40 -35
  72. data/spec/fortnox/api/mappers/contexts/json_conversion.rb +12 -11
  73. data/spec/fortnox/api/mappers/customer_spec.rb +3 -1
  74. data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +3 -1
  75. data/spec/fortnox/api/mappers/edi_information_spec.rb +4 -2
  76. data/spec/fortnox/api/mappers/email_information_spec.rb +4 -2
  77. data/spec/fortnox/api/mappers/examples/mapper.rb +17 -9
  78. data/spec/fortnox/api/mappers/invoice_row_spec.rb +8 -3
  79. data/spec/fortnox/api/mappers/invoice_spec.rb +4 -1
  80. data/spec/fortnox/api/mappers/order_row_spec.rb +9 -2
  81. data/spec/fortnox/api/mappers/order_spec.rb +4 -1
  82. data/spec/fortnox/api/mappers/project_spec.rb +3 -1
  83. data/spec/fortnox/api/mappers/terms_of_payments_spec.rb +16 -0
  84. data/spec/fortnox/api/mappers/unit_spec.rb +57 -0
  85. data/spec/fortnox/api/models/article_spec.rb +2 -0
  86. data/spec/fortnox/api/models/base_spec.rb +46 -38
  87. data/spec/fortnox/api/models/customer_spec.rb +2 -0
  88. data/spec/fortnox/api/models/examples/document_base.rb +5 -3
  89. data/spec/fortnox/api/models/examples/model.rb +12 -9
  90. data/spec/fortnox/api/models/invoice_spec.rb +2 -0
  91. data/spec/fortnox/api/models/order_spec.rb +2 -0
  92. data/spec/fortnox/api/models/project_spec.rb +2 -0
  93. data/spec/fortnox/api/models/terms_of_payments_spec.rb +9 -0
  94. data/spec/fortnox/api/models/unit_spec.rb +31 -0
  95. data/spec/fortnox/api/repositories/article_spec.rb +7 -5
  96. data/spec/fortnox/api/repositories/base_spec.rb +121 -100
  97. data/spec/fortnox/api/repositories/customer_spec.rb +7 -5
  98. data/spec/fortnox/api/repositories/examples/all.rb +5 -4
  99. data/spec/fortnox/api/repositories/examples/find.rb +50 -41
  100. data/spec/fortnox/api/repositories/examples/only.rb +14 -13
  101. data/spec/fortnox/api/repositories/examples/save.rb +23 -29
  102. data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +11 -11
  103. data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +11 -10
  104. data/spec/fortnox/api/repositories/examples/search.rb +15 -15
  105. data/spec/fortnox/api/repositories/invoice_spec.rb +8 -6
  106. data/spec/fortnox/api/repositories/order_spec.rb +8 -6
  107. data/spec/fortnox/api/repositories/project_spec.rb +7 -5
  108. data/spec/fortnox/api/repositories/terms_of_payments_spec.rb +30 -0
  109. data/spec/fortnox/api/repositories/unit_spec.rb +34 -0
  110. data/spec/fortnox/api/types/account_number_spec.rb +12 -9
  111. data/spec/fortnox/api/types/default_delivery_types_spec.rb +6 -4
  112. data/spec/fortnox/api/types/edi_information_spec.rb +9 -7
  113. data/spec/fortnox/api/types/email_information_spec.rb +8 -6
  114. data/spec/fortnox/api/types/email_spec.rb +27 -14
  115. data/spec/fortnox/api/types/enums_spec.rb +3 -1
  116. data/spec/fortnox/api/types/examples/document_row.rb +10 -8
  117. data/spec/fortnox/api/types/examples/enum.rb +29 -22
  118. data/spec/fortnox/api/types/examples/types.rb +8 -4
  119. data/spec/fortnox/api/types/housework_types_spec.rb +68 -0
  120. data/spec/fortnox/api/types/invoice_row_spec.rb +3 -1
  121. data/spec/fortnox/api/types/model_spec.rb +12 -9
  122. data/spec/fortnox/api/types/nullable_spec.rb +8 -6
  123. data/spec/fortnox/api/types/order_row_spec.rb +4 -2
  124. data/spec/fortnox/api/types/required_spec.rb +4 -2
  125. data/spec/fortnox/api/types/sized_spec.rb +18 -16
  126. data/spec/fortnox/api_spec.rb +45 -43
  127. data/spec/spec_helper.rb +9 -6
  128. data/spec/support/helpers.rb +3 -1
  129. data/spec/support/helpers/configuration_helper.rb +2 -0
  130. data/spec/support/helpers/dummy_class_helper.rb +7 -8
  131. data/spec/support/helpers/repository_helper.rb +2 -0
  132. data/spec/support/helpers/when_performing_helper.rb +3 -1
  133. data/spec/support/matchers.rb +2 -0
  134. data/spec/support/matchers/type.rb +3 -1
  135. data/spec/support/matchers/type/attribute_matcher.rb +15 -14
  136. data/spec/support/matchers/type/enum_matcher.rb +9 -7
  137. data/spec/support/matchers/type/have_account_number_matcher.rb +11 -9
  138. data/spec/support/matchers/type/have_country_code_matcher.rb +6 -4
  139. data/spec/support/matchers/type/have_currency_matcher.rb +4 -2
  140. data/spec/support/matchers/type/have_customer_type_matcher.rb +6 -4
  141. data/spec/support/matchers/type/have_default_delivery_type_matcher.rb +4 -2
  142. data/spec/support/matchers/type/have_discount_type_matcher.rb +4 -2
  143. data/spec/support/matchers/type/have_email_matcher.rb +11 -9
  144. data/spec/support/matchers/type/have_housework_type_matcher.rb +9 -0
  145. data/spec/support/matchers/type/have_nullable_date_matcher.rb +29 -29
  146. data/spec/support/matchers/type/have_nullable_matcher.rb +23 -21
  147. data/spec/support/matchers/type/have_nullable_string_matcher.rb +30 -32
  148. data/spec/support/matchers/type/have_sized_float_matcher.rb +4 -2
  149. data/spec/support/matchers/type/have_sized_integer_matcher.rb +4 -2
  150. data/spec/support/matchers/type/have_sized_string_matcher.rb +16 -15
  151. data/spec/support/matchers/type/have_vat_type_matcher.rb +4 -2
  152. data/spec/support/matchers/type/numeric_matcher.rb +25 -23
  153. data/spec/support/matchers/type/require_attribute_matcher.rb +36 -37
  154. data/spec/support/matchers/type/type_matcher.rb +18 -16
  155. data/spec/support/vcr_setup.rb +2 -0
  156. data/spec/vcr_cassettes/orders/{house_work_type_babysitting.yml → housework_type_babysitting.yml} +9 -10
  157. data/spec/vcr_cassettes/orders/{house_work_type_cleaning.yml → housework_type_cleaning.yml} +9 -10
  158. data/spec/vcr_cassettes/orders/{house_work_type_construction.yml → housework_type_construction.yml} +9 -10
  159. data/spec/vcr_cassettes/orders/{house_work_type_cooking.yml → housework_type_cooking.yml} +7 -7
  160. data/spec/vcr_cassettes/orders/{house_work_type_electricity.yml → housework_type_electricity.yml} +9 -10
  161. data/spec/vcr_cassettes/orders/{house_work_type_gardening.yml → housework_type_gardening.yml} +9 -10
  162. data/spec/vcr_cassettes/orders/{house_work_type_glassmetalwork.yml → housework_type_glassmetalwork.yml} +9 -10
  163. data/spec/vcr_cassettes/orders/{house_work_type_grounddrainagework.yml → housework_type_grounddrainagework.yml} +9 -10
  164. data/spec/vcr_cassettes/orders/{house_work_type_hvac.yml → housework_type_hvac.yml} +9 -10
  165. data/spec/vcr_cassettes/orders/{house_work_type_masonry.yml → housework_type_masonry.yml} +9 -10
  166. data/spec/vcr_cassettes/orders/{house_work_type_othercare.yml → housework_type_othercare.yml} +9 -10
  167. data/spec/vcr_cassettes/orders/{house_work_type_othercosts.yml → housework_type_othercosts.yml} +9 -10
  168. data/spec/vcr_cassettes/orders/{house_work_type_paintingwallpapering.yml → housework_type_paintingwallpapering.yml} +9 -10
  169. data/spec/vcr_cassettes/orders/{house_work_type_snowplowing.yml → housework_type_snowplowing.yml} +9 -10
  170. data/spec/vcr_cassettes/orders/{house_work_type_textileclothing.yml → housework_type_textileclothing.yml} +9 -10
  171. data/spec/vcr_cassettes/orders/{house_work_type_tutoring.yml → housework_type_tutoring.yml} +7 -7
  172. data/spec/vcr_cassettes/termsofpayments/all.yml +51 -0
  173. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +45 -0
  174. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +46 -0
  175. data/spec/vcr_cassettes/termsofpayments/find_new.yml +46 -0
  176. data/spec/vcr_cassettes/termsofpayments/save_new.yml +45 -0
  177. data/spec/vcr_cassettes/termsofpayments/save_old.yml +46 -0
  178. data/spec/vcr_cassettes/units/all.yml +48 -0
  179. data/spec/vcr_cassettes/units/find_failure.yml +45 -0
  180. data/spec/vcr_cassettes/units/find_id_1.yml +46 -0
  181. data/spec/vcr_cassettes/units/find_new.yml +48 -0
  182. data/spec/vcr_cassettes/units/save_new.yml +47 -0
  183. data/spec/vcr_cassettes/units/save_old.yml +48 -0
  184. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +47 -0
  185. metadata +127 -88
  186. data/docs/account.rb +0 -59
  187. data/docs/extraction_script.js +0 -23
  188. data/docs/generation_script.rb +0 -43
  189. data/docs/json/account.json +0 -77
  190. data/lib/fortnox/api/models/document_base.rb +0 -189
  191. data/spec/fortnox/api/types/house_work_types_spec.rb +0 -64
  192. data/spec/support/matchers/type/have_house_work_type_matcher.rb +0 -7
@@ -1,16 +1,23 @@
1
- require "fortnox/api/mappers/base"
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/mappers/base'
2
4
 
3
5
  module Fortnox
4
6
  module API
5
7
  module Mapper
6
8
  class OrderRow < Fortnox::API::Mapper::Base
7
- KEY_MAP = { vat: 'VAT' }.freeze
8
- JSON_ENTITY_WRAPPER = 'OrderRow'.freeze
9
- JSON_COLLECTION_WRAPPER = 'OrderRows'.freeze
9
+ KEY_MAP = {
10
+ housework: 'HouseWork',
11
+ housework_hours_to_report: 'HouseWorkHoursToReport',
12
+ housework_type: 'HouseWorkType',
13
+ vat: 'VAT'
14
+ }.freeze
15
+ JSON_ENTITY_WRAPPER = 'OrderRow'
16
+ JSON_COLLECTION_WRAPPER = 'OrderRows'
10
17
  end
11
18
 
12
- Registry.register( OrderRow.canonical_name_sym, OrderRow )
13
- Registry.register( :orderrows, OrderRow )
19
+ Registry.register(OrderRow.canonical_name_sym, OrderRow)
20
+ Registry.register(:orderrows, OrderRow)
14
21
  end
15
22
  end
16
23
  end
@@ -1,15 +1,17 @@
1
- require "fortnox/api/mappers/base"
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/mappers/base'
2
4
 
3
5
  module Fortnox
4
6
  module API
5
7
  module Mapper
6
8
  class Project < Fortnox::API::Mapper::Base
7
9
  KEY_MAP = {}.freeze
8
- JSON_ENTITY_WRAPPER = 'Project'.freeze
9
- JSON_COLLECTION_WRAPPER = 'Projects'.freeze
10
+ JSON_ENTITY_WRAPPER = 'Project'
11
+ JSON_COLLECTION_WRAPPER = 'Projects'
10
12
  end
11
13
 
12
- Registry.register( Project.canonical_name_sym, Project )
14
+ Registry.register(Project.canonical_name_sym, Project)
13
15
  end
14
16
  end
15
17
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/mappers/base'
4
+
5
+ module Fortnox
6
+ module API
7
+ module Mapper
8
+ class TermsOfPayments < Fortnox::API::Mapper::Base
9
+ KEY_MAP = {}.freeze
10
+ JSON_ENTITY_WRAPPER = 'TermsOfPayment'
11
+ JSON_COLLECTION_WRAPPER = 'TermsOfPayments'
12
+ end
13
+
14
+ Registry.register(TermsOfPayments.canonical_name_sym, TermsOfPayments)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/mappers/base'
4
+
5
+ module Fortnox
6
+ module API
7
+ module Mapper
8
+ class Unit < Fortnox::API::Mapper::Base
9
+ KEY_MAP = {}.freeze
10
+ JSON_ENTITY_WRAPPER = 'Unit'
11
+ JSON_COLLECTION_WRAPPER = 'Units'
12
+ end
13
+
14
+ Registry.register(Unit.canonical_name_sym, Unit)
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,9 @@
1
- require "fortnox/api/models/article"
2
- require "fortnox/api/models/customer"
3
- require "fortnox/api/models/invoice"
4
- require "fortnox/api/models/order"
5
- require "fortnox/api/models/project"
1
+ # frozen_string_literal: true
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_payments'
@@ -1,131 +1,132 @@
1
- require "fortnox/api/types"
2
- require "fortnox/api/models/base"
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/types'
4
+ require 'fortnox/api/models/base'
3
5
 
4
6
  module Fortnox
5
7
  module API
6
8
  module Model
7
9
  class Article < Fortnox::API::Model::Base
8
-
9
10
  UNIQUE_ID = :article_number
10
11
  STUB = { description: '' }.freeze
11
12
 
12
- #Url Direct URL to the record
13
- attribute :url, Types::Nullable::String.with( read_only: true )
13
+ # Url Direct URL to the record
14
+ attribute :url, Types::Nullable::String.is(:read_only)
14
15
 
15
- #Active If the article is active
16
+ # Active If the article is active
16
17
  attribute :active, Types::Nullable::Boolean
17
18
 
18
- #ArticleNumber Article number. 50 characters
19
- attribute :article_number, Types::Sized::String[ 50 ]
19
+ # ArticleNumber Article number. 50 characters
20
+ attribute :article_number, Types::Sized::String[50]
20
21
 
21
- #Bulky If the article is bulky.
22
+ # Bulky If the article is bulky.
22
23
  attribute :bulky, Types::Nullable::Boolean
23
24
 
24
- #ConstructionAccount Account number for construction work (special VAT rules in Sweden).
25
+ # ConstructionAccount Account number for construction work (special VAT rules in Sweden).
25
26
  # The number must be of an existing account.
26
- attribute :construction_account, Types::Sized::Integer[ 0, 9_999 ]
27
+ attribute :construction_account, Types::Sized::Integer[0, 9_999]
27
28
 
28
- #Depth The depth of the article in millimeters
29
- attribute :depth, Types::Sized::Integer[ 0, 99_999_999 ]
29
+ # Depth The depth of the article in millimeters
30
+ attribute :depth, Types::Sized::Integer[0, 99_999_999]
30
31
 
31
- #Description The description of the article
32
- attribute :description, Types::Sized::String[ 200 ].with( required: true )
32
+ # Description The description of the article
33
+ attribute :description, Types::Sized::String[200].is(:required)
33
34
 
34
- #DisposableQuantity Disposable quantity of the article.
35
- attribute :disposable_quantity, Types::Nullable::Float.with( read_only: true )
35
+ # DisposableQuantity Disposable quantity of the article.
36
+ attribute :disposable_quantity, Types::Nullable::Float.is(:read_only)
36
37
 
37
- #EAN EAN bar code
38
- attribute :ean, Types::Sized::String[ 30 ]
38
+ # EAN EAN bar code
39
+ attribute :ean, Types::Sized::String[30]
39
40
 
40
- #EUAccount Account number for the sales account to EU.
41
+ # EUAccount Account number for the sales account to EU.
41
42
  # The number must be of an existing account.
42
- attribute :eu_account, Types::Sized::Integer[ 0, 9_999 ]
43
+ attribute :eu_account, Types::Sized::Integer[0, 9_999]
43
44
 
44
- #EUVATAccount Account number for the sales account to EU with VAT.
45
+ # EUVATAccount Account number for the sales account to EU with VAT.
45
46
  # The number must be of an existing account.
46
- attribute :eu_vat_account, Types::Sized::Integer[ 0, 9_999 ]
47
+ attribute :eu_vat_account, Types::Sized::Integer[0, 9_999]
47
48
 
48
- #ExportAccount Account number for the sales account outside EU
49
+ # ExportAccount Account number for the sales account outside EU
49
50
  # The number must be of an existing account.
50
- attribute :export_account, Types::Sized::Integer[ 0, 9_999 ]
51
+ attribute :export_account, Types::Sized::Integer[0, 9_999]
51
52
 
52
- #Height The height of the article in millimeters
53
- attribute :height, Types::Sized::Integer[ 0, 99_999_999 ]
53
+ # Height The height of the article in millimeters
54
+ attribute :height, Types::Sized::Integer[0, 99_999_999]
54
55
 
55
- #Housework If the article is housework
56
+ # Housework If the article is housework
56
57
  attribute :housework, Types::Nullable::Boolean
57
58
 
58
- #HouseWorkType The type of house work.
59
- attribute :house_work_type, Types::HouseWorkType
59
+ # HouseWorkType The type of housework.
60
+ attribute :housework_type, Types::HouseworkType
60
61
 
61
- #Manufacturer The manufacturer of the article
62
- attribute :manufacturer, Types::Sized::String[ 50 ]
62
+ # Manufacturer The manufacturer of the article
63
+ attribute :manufacturer, Types::Sized::String[50]
63
64
 
64
- #ManufacturerArticleNumber The manufacturer's article number
65
- attribute :manufacturer_article_number, Types::Sized::String[ 50 ]
65
+ # ManufacturerArticleNumber The manufacturer's article number
66
+ attribute :manufacturer_article_number, Types::Sized::String[50]
66
67
 
67
- #Note Text note
68
- attribute :note, Types::Sized::String[ 10_000 ]
68
+ # Note Text note
69
+ attribute :note, Types::Sized::String[10_000]
69
70
 
70
- #PurchaseAccount Account number for purchase.
71
+ # PurchaseAccount Account number for purchase.
71
72
  # The number must be of an existing account.
72
- attribute :purchase_account, Types::Sized::Integer[ 0, 9_999 ]
73
+ attribute :purchase_account, Types::Sized::Integer[0, 9_999]
73
74
 
74
- #PurchasePrice Purchase price of the article
75
- attribute :purchase_price, Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
75
+ # PurchasePrice Purchase price of the article
76
+ attribute :purchase_price, Types::Sized::Float[0.0, 99_999_999_999_999.9]
76
77
 
77
- #QuantityInStock Quantity in stock of the article
78
- attribute :quantity_in_stock, Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
78
+ # QuantityInStock Quantity in stock of the article
79
+ attribute :quantity_in_stock, Types::Sized::Float[0.0, 99_999_999_999_999.9]
79
80
 
80
- #ReservedQuantity Reserved quantity of the article
81
- attribute :reserved_quantity, Types::Nullable::Float.with( read_only: true )
81
+ # ReservedQuantity Reserved quantity of the article
82
+ attribute :reserved_quantity, Types::Nullable::Float.is(:read_only)
82
83
 
83
- #SalesAccount Account number for the sales account in Sweden.
84
+ # SalesAccount Account number for the sales account in Sweden.
84
85
  # The number must be of an existing account.
85
- attribute :sales_account, Types::Sized::Integer[ 0, 9_999 ]
86
+ attribute :sales_account, Types::Sized::Integer[0, 9_999]
86
87
 
87
- #SalesPrice Price of article for its default price list
88
- attribute :sales_price, Types::Nullable::Float.with( read_only: true )
88
+ # SalesPrice Price of article for its default price list
89
+ attribute :sales_price, Types::Nullable::Float.is(:read_only)
89
90
 
90
- #StockGoods If the article is stock goods
91
+ # StockGoods If the article is stock goods
91
92
  attribute :stock_goods, Types::Nullable::Boolean
92
93
 
93
- #StockPlace Storage place for the article
94
- attribute :stock_place, Types::Sized::String[ 100 ]
94
+ # StockPlace Storage place for the article
95
+ attribute :stock_place, Types::Sized::String[100]
95
96
 
96
- #StockValue Value in stock of the article
97
- attribute :stock_value, Types::Nullable::Float.with( read_only: true )
97
+ # StockValue Value in stock of the article
98
+ attribute :stock_value, Types::Nullable::Float.is(:read_only)
98
99
 
99
- #StockWarning When to start warning for low quantity in stock
100
- attribute :stock_warning, Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
100
+ # StockWarning When to start warning for low quantity in stock
101
+ attribute :stock_warning, Types::Sized::Float[0.0, 99_999_999_999_999.9]
101
102
 
102
- #SupplierName Name of the supplier
103
- attribute :supplier_name, Types::Nullable::String.with( read_only: true )
103
+ # SupplierName Name of the supplier
104
+ attribute :supplier_name, Types::Nullable::String.is(:read_only)
104
105
 
105
- #SupplierNumber Supplier number for the article.
106
+ # SupplierNumber Supplier number for the article.
106
107
  # The number must be of an existing supplier.
107
108
  attribute :supplier_number, Types::Nullable::String
108
109
 
109
- #Type The type of the article
110
+ # Type The type of the article
110
111
  attribute :type, Types::ArticleType
111
112
 
112
- #Unit Unit code for the article.
113
+ # Unit Unit code for the article.
113
114
  # The code must be of an existing unit.
114
115
  attribute :unit, Types::Nullable::String
115
116
 
116
- #VAT VAT percent, this is predefined by the VAT for the sales account
117
+ # VAT VAT percent, this is predefined by the VAT for the sales account
117
118
  attribute :vat, Types::Nullable::Float
118
119
 
119
- #WebshopArticle If the article is a webshop article
120
+ # WebshopArticle If the article is a webshop article
120
121
  attribute :webshop_article, Types::Nullable::Boolean
121
122
 
122
- #Weight Weight of the article in grams
123
- attribute :weight, Types::Sized::Integer[ 0, 99_999_999 ]
123
+ # Weight Weight of the article in grams
124
+ attribute :weight, Types::Sized::Integer[0, 99_999_999]
124
125
 
125
- #Width Width of the article in millimeters.
126
- attribute :width, Types::Sized::Integer[ 0, 99_999_999 ]
126
+ # Width Width of the article in millimeters.
127
+ attribute :width, Types::Sized::Integer[0, 99_999_999]
127
128
 
128
- #Expired If the article has expired
129
+ # Expired If the article has expired
129
130
  attribute :expired, Types::Nullable::Boolean
130
131
  end
131
132
  end
@@ -1,55 +1,72 @@
1
- require "fortnox/api/types"
2
- require "ice_nine"
1
+ # frozen_string_literal: true
2
+
3
+ require 'fortnox/api/types'
4
+ require 'ice_nine'
3
5
 
4
6
  module Fortnox
5
7
  module API
6
8
  module Model
7
9
  class Base < Fortnox::API::Types::Model
8
-
9
10
  # TODO(jonas): Restructure this class a bit, it is not very readable.
10
11
 
11
- attr_accessor :unsaved, :parent
12
+ attr_accessor :unsaved
13
+ attr_writer :parent
12
14
 
13
- def self.attribute( name, *args )
14
- define_method( "#{ name }?" ) do
15
- !send( name ).nil?
15
+ def self.attribute(name, *args)
16
+ define_method("#{name}?") do
17
+ !send(name).nil?
16
18
  end
17
19
 
18
20
  super
19
21
  end
20
22
 
21
- def self.new( hash )
23
+ def self.new(hash = {})
22
24
  begin
23
- obj = preserve_meta_properties( hash ) do
24
- super( hash )
25
+ obj = preserve_meta_properties(hash) do
26
+ super(hash)
25
27
  end
26
28
  rescue Dry::Struct::Error => e
27
- raise Fortnox::API::AttributeError.new e
29
+ raise Fortnox::API::AttributeError, e
28
30
  end
29
31
 
30
- IceNine.deep_freeze( obj )
32
+ IceNine.deep_freeze(obj)
33
+ end
34
+
35
+ def self.stub
36
+ new(self::STUB.dup)
37
+ end
38
+
39
+ # This filtering logic could be improved since it is currently O(N*M).
40
+ def attributes(*options)
41
+ return self.class.schema if options.nil?
42
+
43
+ options = Array(options)
44
+
45
+ self.class.schema.find_all do |_name, attribute|
46
+ options.all? { |option| attribute.is?(option) }
47
+ end
31
48
  end
32
49
 
33
50
  def unique_id
34
- send( self.class::UNIQUE_ID )
51
+ send(self.class::UNIQUE_ID)
35
52
  end
36
53
 
37
- def update( hash )
38
- old_attributes = self.to_hash
39
- new_attributes = old_attributes.merge( hash )
54
+ def update(hash)
55
+ old_attributes = to_hash
56
+ new_attributes = old_attributes.merge(hash)
40
57
 
41
58
  return self if new_attributes == old_attributes
42
59
 
43
- new_hash = new_attributes.delete_if{ |_, value| value.nil? }
60
+ new_hash = new_attributes.delete_if { |_, value| value.nil? }
44
61
  new_hash[:new] = @new
45
62
  new_hash[:parent] = self
46
- self.class.new( new_hash )
63
+ self.class.new(new_hash)
47
64
  end
48
65
 
49
66
  # Generic comparison, by value, use .eql? or .equal? for object identity.
50
- def ==( other )
67
+ def ==(other)
51
68
  return false unless other.is_a? self.class
52
- self.to_hash == other.to_hash
69
+ to_hash == other.to_hash
53
70
  end
54
71
 
55
72
  def new?
@@ -61,14 +78,14 @@ module Fortnox
61
78
  end
62
79
 
63
80
  def parent?
64
- not @parent.nil?
81
+ !@parent.nil?
65
82
  end
66
83
 
67
84
  def parent
68
- @parent || self.class.new( self.class::STUB.dup )
85
+ @parent || self.class.new(self.class::STUB.dup)
69
86
  end
70
87
 
71
- def to_hash( recursive = false )
88
+ def to_hash(recursive = false)
72
89
  return super() if recursive
73
90
 
74
91
  self.class.schema.keys.each_with_object({}) do |key, result|
@@ -76,34 +93,33 @@ module Fortnox
76
93
  end
77
94
  end
78
95
 
79
- private_class_method
96
+ private_class_method
80
97
 
81
98
  # dry-types filter anything that isn't specified as an attribute on the
82
99
  # class that is being instantiated. This wrapper preserves the meta
83
100
  # properties we need to track object state during that initilisation and
84
101
  # sets them on the object after dry-types is done with it.
85
- def self.preserve_meta_properties( hash )
86
- is_unsaved = hash.delete( :unsaved ){ true }
87
- is_new = hash.delete( :new ){ true }
88
- parent = hash.delete( :parent ){ nil }
102
+ def self.preserve_meta_properties(hash)
103
+ is_unsaved = hash.delete(:unsaved) { true }
104
+ is_new = hash.delete(:new) { true }
105
+ parent = hash.delete(:parent) { nil }
89
106
 
90
107
  obj = yield
91
108
 
92
109
  # TODO: remove new, unsaved, saved
93
- obj.instance_variable_set( :@unsaved, is_unsaved )
94
- obj.instance_variable_set( :@saved, !is_unsaved )
95
- obj.instance_variable_set( :@new, is_new )
96
- obj.instance_variable_set( :@parent, parent )
110
+ obj.instance_variable_set(:@unsaved, is_unsaved)
111
+ obj.instance_variable_set(:@saved, !is_unsaved)
112
+ obj.instance_variable_set(:@new, is_new)
113
+ obj.instance_variable_set(:@parent, parent)
97
114
 
98
- return obj
115
+ obj
99
116
  end
100
117
 
101
- private
118
+ private
102
119
 
103
120
  def private_attributes
104
- @@private_attributes ||= attribute_set.select{ |a| !a.public_writer? }
121
+ @private_attributes ||= attribute_set.reject(&:public_writer?)
105
122
  end
106
-
107
123
  end
108
124
  end
109
125
  end