fortnox-api 0.1.0 → 0.2.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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +3 -2
  3. data/.env.test +3 -0
  4. data/.rubocop.yml +32 -23
  5. data/.travis.yml +3 -2
  6. data/Guardfile +2 -2
  7. data/LICENSE.txt +165 -22
  8. data/README.md +56 -37
  9. data/fortnox-api.gemspec +9 -6
  10. data/lib/fortnox/api.rb +18 -2
  11. data/lib/fortnox/api/base.rb +5 -3
  12. data/lib/fortnox/api/environment_validation.rb +51 -6
  13. data/lib/fortnox/api/mappers.rb +49 -0
  14. data/lib/fortnox/api/mappers/base.rb +47 -0
  15. data/lib/fortnox/api/mappers/base/from_json.rb +78 -0
  16. data/lib/fortnox/api/mappers/base/to_json.rb +65 -0
  17. data/lib/fortnox/api/mappers/customer.rb +27 -0
  18. data/lib/fortnox/api/mappers/default_delivery_types.rb +13 -0
  19. data/lib/fortnox/api/mappers/default_templates.rb +15 -0
  20. data/lib/fortnox/api/mappers/edi_information.rb +22 -0
  21. data/lib/fortnox/api/mappers/email_information.rb +18 -0
  22. data/lib/fortnox/api/mappers/invoice.rb +27 -0
  23. data/lib/fortnox/api/mappers/invoice_row.rb +20 -0
  24. data/lib/fortnox/api/mappers/order.rb +23 -0
  25. data/lib/fortnox/api/mappers/order_row.rb +16 -0
  26. data/lib/fortnox/api/models.rb +2 -0
  27. data/lib/fortnox/api/models/base.rb +56 -13
  28. data/lib/fortnox/api/models/customer.rb +112 -101
  29. data/lib/fortnox/api/models/document_base.rb +189 -0
  30. data/lib/fortnox/api/models/invoice.rb +29 -195
  31. data/lib/fortnox/api/models/label.rb +17 -0
  32. data/lib/fortnox/api/models/order.rb +27 -0
  33. data/lib/fortnox/api/repositories.rb +2 -0
  34. data/lib/fortnox/api/repositories/base.rb +4 -5
  35. data/lib/fortnox/api/repositories/base/loaders.rb +22 -14
  36. data/lib/fortnox/api/repositories/base/savers.rb +30 -16
  37. data/lib/fortnox/api/repositories/customer.rb +3 -25
  38. data/lib/fortnox/api/repositories/invoice.rb +3 -22
  39. data/lib/fortnox/api/repositories/order.rb +16 -0
  40. data/lib/fortnox/api/request_handling.rb +3 -3
  41. data/lib/fortnox/api/types.rb +44 -0
  42. data/lib/fortnox/api/types/default_delivery_types.rb +20 -0
  43. data/lib/fortnox/api/types/default_templates.rb +23 -0
  44. data/lib/fortnox/api/types/defaulted.rb +11 -0
  45. data/lib/fortnox/api/types/document_row.rb +65 -0
  46. data/lib/fortnox/api/types/edi_information.rb +29 -0
  47. data/lib/fortnox/api/types/email_information.rb +26 -0
  48. data/lib/fortnox/api/types/enums.rb +75 -0
  49. data/lib/fortnox/api/types/invoice_row.rb +19 -0
  50. data/lib/fortnox/api/types/model.rb +40 -0
  51. data/lib/fortnox/api/types/nullable.rb +21 -0
  52. data/lib/fortnox/api/types/order_row.rb +16 -0
  53. data/lib/fortnox/api/types/required.rb +13 -0
  54. data/lib/fortnox/api/types/sized.rb +25 -0
  55. data/lib/fortnox/api/version.rb +1 -1
  56. data/spec/fortnox/api/base_spec.rb +85 -14
  57. data/spec/fortnox/api/mappers/base/from_json_spec.rb +70 -0
  58. data/spec/fortnox/api/mappers/base/to_json_spec.rb +76 -0
  59. data/spec/fortnox/api/mappers/base_spec.rb +156 -0
  60. data/spec/fortnox/api/mappers/contexts/json_conversion.rb +56 -0
  61. data/spec/fortnox/api/mappers/customer_spec.rb +25 -0
  62. data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +12 -0
  63. data/spec/fortnox/api/mappers/edi_information_spec.rb +21 -0
  64. data/spec/fortnox/api/mappers/email_information_spec.rb +17 -0
  65. data/spec/fortnox/api/mappers/examples/mapper.rb +26 -0
  66. data/spec/fortnox/api/mappers/invoice_row_spec.rb +19 -0
  67. data/spec/fortnox/api/mappers/invoice_spec.rb +24 -0
  68. data/spec/fortnox/api/mappers/order_row_spec.rb +14 -0
  69. data/spec/fortnox/api/mappers/order_spec.rb +20 -0
  70. data/spec/fortnox/api/models/base_spec.rb +44 -22
  71. data/spec/fortnox/api/models/customer_spec.rb +9 -0
  72. data/spec/fortnox/api/models/examples/document_base.rb +13 -0
  73. data/spec/fortnox/api/models/examples/model.rb +13 -0
  74. data/spec/fortnox/api/models/invoice_spec.rb +7 -31
  75. data/spec/fortnox/api/models/order_spec.rb +13 -0
  76. data/spec/fortnox/api/repositories/customer_spec.rb +20 -76
  77. data/spec/fortnox/api/repositories/examples/all.rb +17 -0
  78. data/spec/fortnox/api/repositories/examples/find.rb +25 -0
  79. data/spec/fortnox/api/repositories/examples/only.rb +42 -0
  80. data/spec/fortnox/api/repositories/examples/save.rb +69 -0
  81. data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +32 -0
  82. data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +27 -0
  83. data/spec/fortnox/api/repositories/examples/search.rb +31 -0
  84. data/spec/fortnox/api/repositories/invoice_spec.rb +36 -5
  85. data/spec/fortnox/api/repositories/order_spec.rb +35 -0
  86. data/spec/fortnox/api/types/account_number_spec.rb +28 -0
  87. data/spec/fortnox/api/types/default_delivery_types_spec.rb +10 -0
  88. data/spec/fortnox/api/types/edi_information_spec.rb +13 -0
  89. data/spec/fortnox/api/types/email_information_spec.rb +13 -0
  90. data/spec/fortnox/api/types/email_spec.rb +29 -0
  91. data/spec/fortnox/api/types/enums_spec.rb +13 -0
  92. data/spec/fortnox/api/types/examples/document_row.rb +15 -0
  93. data/spec/fortnox/api/types/examples/enum.rb +48 -0
  94. data/spec/fortnox/api/types/examples/types.rb +9 -0
  95. data/spec/fortnox/api/types/house_work_types_spec.rb +60 -0
  96. data/spec/fortnox/api/types/invoice_row_spec.rb +9 -0
  97. data/spec/fortnox/api/types/model_spec.rb +56 -0
  98. data/spec/fortnox/api/types/nullable_spec.rb +57 -0
  99. data/spec/fortnox/api/types/order_row_spec.rb +13 -0
  100. data/spec/fortnox/api/types/required_spec.rb +42 -0
  101. data/spec/fortnox/api/types/sized_spec.rb +74 -0
  102. data/spec/fortnox/api_spec.rb +16 -15
  103. data/spec/spec_helper.rb +19 -9
  104. data/spec/support/helpers/dummy_class_helper.rb +19 -0
  105. data/spec/support/helpers/environment_helper.rb +7 -0
  106. data/spec/support/helpers/repository_helper.rb +8 -0
  107. data/spec/support/helpers/when_performing_helper.rb +5 -0
  108. data/spec/support/matchers.rb +1 -1
  109. data/spec/support/matchers/type.rb +17 -0
  110. data/spec/support/matchers/type/attribute_matcher.rb +39 -0
  111. data/spec/support/matchers/type/enum_matcher.rb +21 -0
  112. data/spec/support/matchers/type/have_account_number_matcher.rb +21 -0
  113. data/spec/support/matchers/type/have_country_code_matcher.rb +13 -0
  114. data/spec/support/matchers/type/have_currency_matcher.rb +7 -0
  115. data/spec/support/matchers/type/have_customer_type_matcher.rb +13 -0
  116. data/spec/support/matchers/type/have_default_delivery_type_matcher.rb +7 -0
  117. data/spec/support/matchers/type/have_discount_type_matcher.rb +7 -0
  118. data/spec/support/matchers/type/have_email_matcher.rb +22 -0
  119. data/spec/support/matchers/type/have_house_work_type_matcher.rb +7 -0
  120. data/spec/support/matchers/type/have_nullable_date_matcher.rb +58 -0
  121. data/spec/support/matchers/type/have_nullable_matcher.rb +52 -0
  122. data/spec/support/matchers/type/have_nullable_string_matcher.rb +49 -0
  123. data/spec/support/matchers/type/have_sized_float_matcher.rb +8 -0
  124. data/spec/support/matchers/type/have_sized_integer_matcher.rb +8 -0
  125. data/spec/support/matchers/type/have_sized_string_matcher.rb +35 -0
  126. data/spec/support/matchers/type/have_vat_type_matcher.rb +7 -0
  127. data/spec/support/matchers/type/numeric_matcher.rb +50 -0
  128. data/spec/support/matchers/type/require_attribute_matcher.rb +69 -0
  129. data/spec/support/matchers/type/type_matcher.rb +38 -0
  130. data/spec/vcr_cassettes/customers/all.yml +119 -9
  131. data/spec/vcr_cassettes/customers/find_id_1.yml +8 -9
  132. data/spec/vcr_cassettes/customers/find_new.yml +46 -0
  133. data/spec/vcr_cassettes/customers/save_new.yml +9 -11
  134. data/spec/vcr_cassettes/customers/save_old.yml +9 -12
  135. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +45 -0
  136. data/spec/vcr_cassettes/customers/search_by_name.yml +66 -0
  137. data/spec/vcr_cassettes/customers/search_miss.yml +45 -0
  138. data/spec/vcr_cassettes/invoices/all.yml +104 -0
  139. data/spec/vcr_cassettes/invoices/filter_hit.yml +46 -0
  140. data/spec/vcr_cassettes/invoices/filter_invalid.yml +42 -0
  141. data/spec/vcr_cassettes/invoices/find_id_1.yml +47 -0
  142. data/spec/vcr_cassettes/invoices/find_new.yml +49 -0
  143. data/spec/vcr_cassettes/invoices/save_new.yml +48 -0
  144. data/spec/vcr_cassettes/invoices/save_old.yml +49 -0
  145. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +47 -0
  146. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +47 -0
  147. data/spec/vcr_cassettes/invoices/search_by_name.yml +48 -0
  148. data/spec/vcr_cassettes/invoices/search_miss.yml +45 -0
  149. data/spec/vcr_cassettes/orders/all.yml +144 -0
  150. data/spec/vcr_cassettes/orders/filter_hit.yml +48 -0
  151. data/spec/vcr_cassettes/orders/filter_invalid.yml +42 -0
  152. data/spec/vcr_cassettes/orders/find_id_1.yml +48 -0
  153. data/spec/vcr_cassettes/orders/find_new.yml +49 -0
  154. data/spec/vcr_cassettes/orders/house_work_type_babysitting.yml +47 -0
  155. data/spec/vcr_cassettes/orders/house_work_type_cleaning.yml +47 -0
  156. data/spec/vcr_cassettes/orders/house_work_type_construction.yml +47 -0
  157. data/spec/vcr_cassettes/orders/house_work_type_cooking.yml +43 -0
  158. data/spec/vcr_cassettes/orders/house_work_type_electricity.yml +47 -0
  159. data/spec/vcr_cassettes/orders/house_work_type_gardening.yml +47 -0
  160. data/spec/vcr_cassettes/orders/house_work_type_glassmetalwork.yml +47 -0
  161. data/spec/vcr_cassettes/orders/house_work_type_grounddrainagework.yml +47 -0
  162. data/spec/vcr_cassettes/orders/house_work_type_hvac.yml +47 -0
  163. data/spec/vcr_cassettes/orders/house_work_type_masonry.yml +47 -0
  164. data/spec/vcr_cassettes/orders/house_work_type_othercare.yml +47 -0
  165. data/spec/vcr_cassettes/orders/house_work_type_othercosts.yml +47 -0
  166. data/spec/vcr_cassettes/orders/house_work_type_paintingwallpapering.yml +47 -0
  167. data/spec/vcr_cassettes/orders/house_work_type_snowplowing.yml +47 -0
  168. data/spec/vcr_cassettes/orders/house_work_type_textileclothing.yml +47 -0
  169. data/spec/vcr_cassettes/orders/house_work_type_tutoring.yml +43 -0
  170. data/spec/vcr_cassettes/orders/save_new.yml +48 -0
  171. data/spec/vcr_cassettes/orders/save_old.yml +49 -0
  172. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +47 -0
  173. data/spec/vcr_cassettes/orders/search_by_name.yml +47 -0
  174. data/spec/vcr_cassettes/orders/search_miss.yml +45 -0
  175. metadata +301 -71
  176. data/lib/fortnox/api/models/attributes/country_code.rb +0 -17
  177. data/lib/fortnox/api/models/attributes/currency.rb +0 -17
  178. data/lib/fortnox/api/models/edi_information.rb +0 -28
  179. data/lib/fortnox/api/models/email_information.rb +0 -25
  180. data/lib/fortnox/api/models/row.rb +0 -82
  181. data/lib/fortnox/api/repositories/base/json_convertion.rb +0 -68
  182. data/lib/fortnox/api/repositories/base/options.rb +0 -33
  183. data/lib/fortnox/api/validators.rb +0 -1
  184. data/lib/fortnox/api/validators/attributes/country_code.rb +0 -42
  185. data/lib/fortnox/api/validators/attributes/currency.rb +0 -38
  186. data/lib/fortnox/api/validators/base.rb +0 -70
  187. data/lib/fortnox/api/validators/constant.rb +0 -21
  188. data/lib/fortnox/api/validators/customer.rb +0 -29
  189. data/lib/fortnox/api/validators/edi_information.rb +0 -11
  190. data/lib/fortnox/api/validators/email_information.rb +0 -19
  191. data/lib/fortnox/api/validators/invoice.rb +0 -33
  192. data/lib/fortnox/api/validators/row.rb +0 -22
  193. data/spec/fortnox/api/models/attributes/country_code_spec.rb +0 -23
  194. data/spec/fortnox/api/models/attributes/currency_spec.rb +0 -23
  195. data/spec/fortnox/api/models/attributes/dummy_model_context.rb +0 -9
  196. data/spec/fortnox/api/models/row_spec.rb +0 -13
  197. data/spec/fortnox/api/repositories/context.rb +0 -10
  198. data/spec/fortnox/api/repositories/examples.rb +0 -16
  199. data/spec/fortnox/api/validators/attributes/country_code_spec.rb +0 -9
  200. data/spec/fortnox/api/validators/attributes/currency_spec.rb +0 -9
  201. data/spec/fortnox/api/validators/attributes/examples_for_validate.rb +0 -29
  202. data/spec/fortnox/api/validators/base_spec.rb +0 -61
  203. data/spec/fortnox/api/validators/constant_spec.rb +0 -12
  204. data/spec/fortnox/api/validators/context.rb +0 -102
  205. data/spec/fortnox/api/validators/customer_spec.rb +0 -31
  206. data/spec/fortnox/api/validators/edi_information_spec.rb +0 -18
  207. data/spec/fortnox/api/validators/email_information_spec.rb +0 -26
  208. data/spec/fortnox/api/validators/invoice_spec.rb +0 -36
  209. data/spec/fortnox/api/validators/row_spec.rb +0 -27
  210. data/spec/fortnox/api/validators/validator_examples.rb +0 -20
  211. data/spec/support/matchers/models.rb +0 -27
  212. data/spec/support/matchers/validators.rb +0 -36
@@ -0,0 +1,17 @@
1
+ require "fortnox/api/types"
2
+
3
+ module Fortnox
4
+ module API
5
+ module Model
6
+ class Label < Model::Base
7
+ STUB = {}.freeze
8
+
9
+ # Id integer, read-only. The ID of the label.
10
+ attribute :id, Types::Required::Integer.with( read_only: true )
11
+
12
+ # Description string, 25 characters, required. Description of the label
13
+ attribute :description, Types::Sized::String[ 25 ].with( read_only: true )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require "fortnox/api/models/base"
2
+ require "fortnox/api/models/document_base"
3
+
4
+ module Fortnox
5
+ module API
6
+ module Model
7
+ class Order < Fortnox::API::Model::Base
8
+ UNIQUE_ID = :document_number
9
+ STUB = { customer_number: '', order_rows: [] }.freeze
10
+
11
+ DocumentBase.ify( self )
12
+
13
+ #CopyRemarks I remarks shall copies from order to invoice
14
+ attribute :copy_remarks, Types::Nullable::Boolean
15
+
16
+ # InvoiceReference Reference if an invoice is created from order
17
+ attribute :invoice_reference, Types::Nullable::Integer.with( read_only: true )
18
+
19
+ # OrderDate Date of order
20
+ attribute :order_date, Types::Nullable::Date
21
+
22
+ # OrderRows Separate object
23
+ attribute :order_rows, Types::Strict::Array.member( Types::OrderRow )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1 +1,3 @@
1
1
  require "fortnox/api/repositories/customer"
2
+ require "fortnox/api/repositories/invoice"
3
+ require "fortnox/api/repositories/order"
@@ -1,5 +1,4 @@
1
1
  require "fortnox/api/base"
2
- require "fortnox/api/repositories/base/json_convertion"
3
2
  require "fortnox/api/repositories/base/loaders"
4
3
  require "fortnox/api/repositories/base/savers"
5
4
 
@@ -8,16 +7,16 @@ module Fortnox
8
7
  module Repository
9
8
  class Base < Fortnox::API::Base
10
9
 
11
- include JSONConvertion
12
10
  include Loaders
13
11
  include Savers
14
12
 
15
- require "fortnox/api/repositories/base/options"
13
+ attr_reader :mapper, :keys_filtered_on_save
16
14
 
17
- def initialize( options )
15
+ def initialize( keys_filtered_on_save: [ :url ] )
18
16
  super()
19
17
 
20
- @options = options
18
+ @keys_filtered_on_save = keys_filtered_on_save
19
+ @mapper = Registry[ Mapper::Base.canonical_name_sym( self.class::MODEL )].new
21
20
  end
22
21
 
23
22
  private
@@ -6,19 +6,19 @@ module Fortnox
6
6
  module Loaders
7
7
 
8
8
  def all()
9
- response_hash = get( @options.uri )
10
- entities_hash = response_hash[ @options.json_collection_wrapper ]
11
- entities_hash.map do |entity_hash|
12
- hash_to_entity( entity_hash )
13
- end
9
+ response_hash = get( self.class::URI )
10
+ instansiate_collection_response( response_hash )
14
11
  end
15
12
 
16
13
  def only( filter )
17
- response_hash = get( @options.uri + "?filter=#{ filter }" )
18
- entities_hash = response_hash[ @options.json_collection_wrapper ]
19
- entities_hash.map do |entity_hash|
20
- hash_to_entity( entity_hash )
21
- end
14
+ response_hash = get( "#{ self.class::URI }?filter=#{ filter }" )
15
+ instansiate_collection_response( response_hash )
16
+ end
17
+
18
+ def search( hash )
19
+ attribute, value = hash.first
20
+ response_hash = get( "#{ self.class::URI }?#{ attribute }=#{ value }" )
21
+ instansiate_collection_response( response_hash )
22
22
  end
23
23
 
24
24
  def find( id_or_hash )
@@ -32,9 +32,8 @@ module Fortnox
32
32
  end
33
33
 
34
34
  def find_one_by( id )
35
- response_hash = get( "#{@options.uri}#{id}" )
36
- entity_hash = response_hash[ @options.json_entity_wrapper ]
37
- hash_to_entity( entity_hash )
35
+ response_hash = get( "#{ self.class::URI }#{ id }" )
36
+ instansiate( @mapper.wrapped_json_hash_to_entity_hash( response_hash ) )
38
37
  end
39
38
 
40
39
  # def find_all_by( hash )
@@ -48,9 +47,18 @@ module Fortnox
48
47
  end
49
48
 
50
49
  def escape( key, value )
51
- "#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
50
+ "#{ CGI.escape(key.to_s) }=#{ CGI.escape(value.to_s) }"
52
51
  end
53
52
 
53
+ private
54
+
55
+ def instansiate_collection_response( response_hash )
56
+ entities_hash = @mapper.wrapped_json_collection_to_entities_hash( response_hash )
57
+ entities_hash.map do |entity_hash|
58
+ instansiate( entity_hash )
59
+ end
60
+ end
61
+
54
62
  end
55
63
  end
56
64
  end
@@ -6,32 +6,46 @@ module Fortnox
6
6
  def save( entity )
7
7
  return true if entity.saved?
8
8
 
9
- hash = entity_to_hash( entity )
10
-
11
- return save_new( hash ) if entity.new?
12
- update_existing( hash )
9
+ return save_new( entity ) if entity.new?
10
+ update_existing( entity )
13
11
  end
14
12
 
15
13
  private
14
+ def execute_save( entity )
15
+ body = get_changes_on( entity ).to_json
16
+ result = yield body
17
+ instansiate_saved( result )
18
+ end
16
19
 
17
- def save_new( hash )
18
- post( @options.uri, { body: hash.to_json } )
20
+ def save_new( entity )
21
+ execute_save( entity ) do |body|
22
+ post( self.class::URI, { body: body })
23
+ end
19
24
  end
20
25
 
21
- def update_existing( hash )
22
- put(
23
- entity_url( hash ),
24
- { body: hash.to_json }
25
- )
26
+ def update_existing( entity )
27
+ execute_save( entity ) do |body|
28
+ put( get_update_url_for( entity ), { body: body })
29
+ end
26
30
  end
27
31
 
28
- def entity_url( hash )
29
- id = cut_id_from_hash( hash )
30
- "#{ @options.uri }#{ id }"
32
+ def get_changes_on( entity )
33
+ hash = @mapper.entity_to_hash( entity, @keys_filtered_on_save )
34
+ parent_hash = @mapper.entity_to_hash( entity.parent, @keys_filtered_on_save )
35
+
36
+ @mapper.wrapp_entity_json_hash( @mapper.diff( hash, parent_hash ) )
31
37
  end
32
38
 
33
- def cut_id_from_hash( hash )
34
- hash[ @options.json_entity_wrapper ].delete( @options.unique_id )
39
+ def get_update_url_for( entity )
40
+ "#{ self.class::URI }#{ entity.unique_id }"
41
+ end
42
+
43
+ def instansiate_saved( wrapped_json_hash )
44
+ instansiate(
45
+ @mapper.wrapped_json_hash_to_entity_hash(
46
+ wrapped_json_hash
47
+ )
48
+ )
35
49
  end
36
50
  end
37
51
  end
@@ -1,37 +1,15 @@
1
1
  require "fortnox/api/repositories/base"
2
2
  require "fortnox/api/models/customer"
3
+ require "fortnox/api/mappers/customer"
3
4
 
4
5
  module Fortnox
5
6
  module API
6
7
  module Repository
7
8
  class Customer < Fortnox::API::Repository::Base
8
9
 
9
- CONFIGURATION = Fortnox::API::Repository::Base::Options.new(
10
- uri: '/customers/',
11
- json_collection_wrapper: 'Customers',
12
- json_entity_wrapper: 'Customer',
13
- unique_id: 'CustomerNumber',
14
- attribute_name_to_json_key_map: {
15
- vat_type: 'VATType',
16
- vat_number: 'VATNumber',
17
- email_invoice_bcc: 'EmailInvoiceBCC',
18
- email_invoice_cc: 'EmailInvoiceCC',
19
- email_offer_bcc: 'EmailOfferBCC',
20
- email_offer_cc: 'EmailOfferCC',
21
- email_order_bcc: 'EmailOrderBCC',
22
- email_order_cc: 'EmailOrderCC',
23
- show_price_vat_included: 'ShowPriceVATIncluded',
24
- },
25
- keys_filtered_on_save: [
26
- :url,
27
- ]
28
- )
29
10
  MODEL = Fortnox::API::Model::Customer
30
-
31
- def initialize
32
- super( CONFIGURATION )
33
- end
34
-
11
+ MAPPER = Fortnox::API::Mapper::Customer
12
+ URI = '/customers/'.freeze
35
13
  end
36
14
  end
37
15
  end
@@ -1,34 +1,15 @@
1
1
  require "fortnox/api/repositories/base"
2
2
  require "fortnox/api/models/invoice"
3
+ require "fortnox/api/mappers/invoice"
3
4
 
4
5
  module Fortnox
5
6
  module API
6
7
  module Repository
7
8
  class Invoice < Fortnox::API::Repository::Base
8
9
 
9
- CONFIGURATION = Fortnox::API::Repository::Base::Options.new(
10
- uri: '/invoices/',
11
- json_collection_wrapper: 'Invoices',
12
- json_entity_wrapper: 'Invoice',
13
- unique_id: 'DocumentNumber',
14
- attribute_name_to_json_key_map: {
15
- administration_fee_vat: 'AdministrationFeeVAT',
16
- edi_information: 'EDIInformation',
17
- eu_quarterly_report: 'EUQuarterlyReport',
18
- freight_vat: 'FreightVAT',
19
- ocr: 'OCR',
20
- total_vat: 'TotalVAT',
21
- vat_included: 'VATIncluded'
22
- },
23
- keys_filtered_on_save: [
24
- :url,
25
- ]
26
- )
27
10
  MODEL = Fortnox::API::Model::Invoice
28
-
29
- def initialize
30
- super( CONFIGURATION )
31
- end
11
+ MAPPER = Fortnox::API::Mapper::Invoice
12
+ URI = '/invoices/'.freeze
32
13
  end
33
14
  end
34
15
  end
@@ -0,0 +1,16 @@
1
+ require "fortnox/api/repositories/base"
2
+ require "fortnox/api/models/order"
3
+ require "fortnox/api/mappers/order"
4
+
5
+ module Fortnox
6
+ module API
7
+ module Repository
8
+ class Order < Fortnox::API::Repository::Base
9
+
10
+ MODEL = Fortnox::API::Model::Order
11
+ MAPPER = Fortnox::API::Mapper::Order
12
+ URI = '/orders/'.freeze
13
+ end
14
+ end
15
+ end
16
+ end
@@ -7,7 +7,7 @@ module Fortnox
7
7
  def raise_api_error( error, response )
8
8
  message = ( error[ 'message' ] || error[ 'Message' ] || 'Okänt fel' )
9
9
 
10
- message += "\n\n#{response.request.inspect}" if Fortnox::API.debugging
10
+ message += "\n\n#{ response.request.inspect }" if Fortnox::API.debugging
11
11
 
12
12
  raise Fortnox::API::RemoteServerError, message
13
13
  end
@@ -24,9 +24,9 @@ module Fortnox
24
24
  response.parsed_response
25
25
  end
26
26
 
27
- def execute &request
27
+ def execute
28
28
  self.class.set_headers( @headers )
29
- response = request.call( self.class )
29
+ response = yield( self.class )
30
30
  validate_and_parse response
31
31
  end
32
32
 
@@ -0,0 +1,44 @@
1
+ require 'dry-struct'
2
+ require 'dry-types'
3
+
4
+ module Fortnox
5
+ module API
6
+ module Types
7
+ include Dry::Types.module
8
+
9
+ THE_TRUTH = { true => true, 'true' => true, false => false, 'false' => false }.freeze
10
+
11
+ require 'fortnox/api/types/required'
12
+ require 'fortnox/api/types/defaulted'
13
+ require 'fortnox/api/types/nullable'
14
+
15
+ require 'fortnox/api/types/enums'
16
+
17
+ require 'fortnox/api/types/sized'
18
+
19
+ AccountNumber = Strict::Int.constrained( gt: 0, lteq: 9999 ).optional
20
+
21
+ CountryCode = Strict::String.constrained( included_in: CountryCodes.values ).optional.constructor( EnumConstructors.sized(2) )
22
+ Currency = Strict::String.constrained( included_in: Currencies.values ).optional.constructor( EnumConstructors.sized(3) )
23
+ CustomerType = Strict::String.constrained( included_in: CustomerTypes.values ).optional.constructor( EnumConstructors.default )
24
+
25
+ DiscountType = Strict::String.constrained( included_in: DiscountTypes.values ).optional.constructor( EnumConstructors.default )
26
+
27
+ Email = Strict::String.constrained( max_size: 1024, format: /\A^$|[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i ).optional.constructor{ |v| v.to_s.downcase unless v.nil? }
28
+
29
+ HouseWorkType = Strict::String.constrained( included_in: HouseWorkTypes.values ).optional.constructor( EnumConstructors.default )
30
+
31
+ VATType = Strict::String.constrained( included_in: VATTypes.values ).optional.constructor( EnumConstructors.default )
32
+
33
+ DefaultDeliveryType = Strict::String.constrained( included_in: DefaultDeliveryTypeValues.values ).optional.constructor( EnumConstructors.default )
34
+
35
+ require 'fortnox/api/types/model'
36
+ require 'fortnox/api/types/default_delivery_types'
37
+ require 'fortnox/api/types/default_templates'
38
+ require 'fortnox/api/types/email_information'
39
+ require 'fortnox/api/types/edi_information'
40
+ require 'fortnox/api/types/invoice_row'
41
+ require 'fortnox/api/types/order_row'
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ require 'fortnox/api/types'
2
+
3
+ module Fortnox
4
+ module API
5
+ module Types
6
+ class DefaultDeliveryTypes < Types::Model
7
+ STUB = {}.freeze
8
+
9
+ #Default delivery type for invoices. Can be PRINT EMAIL or PRINTSERVICE.
10
+ attribute :invoice, Types::DefaultDeliveryType
11
+
12
+ #Default delivery type for orders. Can be PRINT EMAIL or PRINTSERVICE.
13
+ attribute :order, Types::DefaultDeliveryType
14
+
15
+ #Default delivery type for offers. Can be PRINT EMAIL or PRINTSERVICE.
16
+ attribute :offer, Types::DefaultDeliveryType
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ require "fortnox/api/types"
2
+
3
+ module Fortnox
4
+ module API
5
+ module Types
6
+ class DefaultTemplates < Types::Model
7
+ STUB = {}.freeze
8
+
9
+ # Default template for orders. Must be a name of an existing print template.
10
+ attribute :order, Types::Required::String
11
+
12
+ # Default template for offers. Must be a name of an existing print template.
13
+ attribute :offer, Types::Required::String
14
+
15
+ # Default template for invoices. Must be a name of an existing print template.
16
+ attribute :invoice, Types::Required::String
17
+
18
+ # Default template for cash invoices. Must be a name of an existing print template.
19
+ attribute :cash_invoice, Types::Required::String
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module Fortnox
2
+ module API
3
+ module Types
4
+
5
+ module Defaulted
6
+ String = Types::Strict::String.default('')
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,65 @@
1
+ module Fortnox
2
+ module API
3
+ module Types
4
+ module DocumentRow
5
+ def self.ify( base )
6
+ base.class_eval do
7
+ #AccountNumber Account number. 4 digits
8
+ attribute :account_number, Types::AccountNumber
9
+
10
+ #ArticleNumber Article number. 50 characters
11
+ attribute :article_number, Types::Sized::String[ 50 ]
12
+
13
+ #ContributionPercent Contribution Percent.
14
+ attribute :contribution_percent, Types::Nullable::Float.with( private: true )
15
+
16
+ #ContributionValue Contribution Value.
17
+ attribute :contribution_value, Types::Nullable::Float.with( private: true )
18
+
19
+ #CostCenter Code of the cost center for the row.
20
+ attribute :cost_center, Types::Nullable::String
21
+
22
+ #DeliveredQuantity Delivered quantity. 14 digits
23
+ attribute :delivered_quantity, Types::Sized::Float[ 0.0, 9_999_999_999_999.0 ]
24
+
25
+ #Description Description Row description. 50 characters
26
+ attribute :description, Types::Sized::String[ 50 ]
27
+
28
+ # Discount amount. 12 digits (for amount) / 5 digits (for percent)
29
+ # TODO(hannes): Verify that we can send in more than 5 digits through
30
+ # the actual API for DiscountType PERCENT. This cannot be done until
31
+ # we fix issue #62...
32
+ attribute :discount, Types::Sized::Float[ 0.0, 99_999_999_999.0 ]
33
+
34
+ #DiscountType The type of discount used for the row.
35
+ attribute :discount_type, Types::DiscountType
36
+
37
+ #HouseWork If the row is housework
38
+ attribute :house_work, Types::Nullable::Boolean
39
+
40
+ #HouseWorkHoursToReport Hours to be reported if the quantity of the row should not be used as hours. 5 digits
41
+ attribute :house_work_hours_to_report, Types::Sized::Integer[ 0, 99_999 ]
42
+
43
+ #HouseWorkType The type of house work.
44
+ attribute :house_work_type, Types::HouseWorkType
45
+
46
+ #Price Price per unit. 12 digits
47
+ attribute :price, Types::Sized::Float[ 0.0, 99_999_999_999.0 ]
48
+
49
+ #Project Code of the project for the row.
50
+ attribute :project, Types::Nullable::String
51
+
52
+ #Total Total amount for the row.
53
+ attribute :total, Types::Nullable::Float.with( private: true )
54
+
55
+ #Unit Code of the unit for the row.
56
+ attribute :unit, Types::Nullable::String
57
+
58
+ #VAT VAT percentage of the row.
59
+ attribute :vat, Types::Nullable::Integer
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end