fortnox-api 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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