fortnox-api 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -17
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +127 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +131 -7
- data/Rakefile +5 -1
- data/fortnox-api.gemspec +13 -3
- data/lib/fortnox/api.rb +11 -1
- data/lib/fortnox/api/base.rb +56 -0
- data/lib/fortnox/api/class_methods.rb +62 -0
- data/lib/fortnox/api/customer.rb +15 -0
- data/lib/fortnox/api/customer/entity.rb +179 -0
- data/lib/fortnox/api/customer/repository.rb +28 -0
- data/lib/fortnox/api/customer/validator.rb +26 -0
- data/lib/fortnox/api/entity.rb +45 -0
- data/lib/fortnox/api/repository/base.rb +27 -0
- data/lib/fortnox/api/repository/json_convertion.rb +55 -0
- data/lib/fortnox/api/repository/loaders.rb +49 -0
- data/lib/fortnox/api/repository/savers.rb +15 -0
- data/lib/fortnox/api/validator.rb +32 -0
- data/lib/fortnox/api/version.rb +1 -1
- data/spec/fortnox/api/base_spec.rb +93 -0
- data/spec/fortnox/api/customer/repository_spec.rb +0 -0
- data/spec/fortnox/api/customer/validator_spec.rb +32 -0
- data/spec/fortnox/api/entity_spec.rb +62 -0
- data/spec/spec_helper.rb +19 -0
- metadata +163 -8
@@ -0,0 +1,62 @@
|
|
1
|
+
module Fortnox
|
2
|
+
module API
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def get_access_token( base_url: nil, client_secret: nil, authorization_code: nil )
|
6
|
+
base_url = validate_base_url( base_url )
|
7
|
+
client_secret = validate_client_secret( client_secret )
|
8
|
+
authorization_code = validate_authorization_code( authorization_code )
|
9
|
+
|
10
|
+
base_uri( base_url )
|
11
|
+
|
12
|
+
set_headers(
|
13
|
+
'Accept' => 'application/json',
|
14
|
+
'Client-Secret' => client_secret,
|
15
|
+
'Authorisation-Code' => authorization_code,
|
16
|
+
)
|
17
|
+
|
18
|
+
response = get('/')
|
19
|
+
response[ 'Authorisation' ][ 'AccessToken' ]
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_header( name: nil, value: nil )
|
23
|
+
headers[ name ] = value
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_headers( headers = {} )
|
27
|
+
headers.each do |name, value|
|
28
|
+
set_header( name: name, value: value )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_header( name: nil )
|
33
|
+
headers.delete( name )
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_base_url( base_url )
|
37
|
+
base_url ||= ENV['FORTNOX_API_BASE_URL']
|
38
|
+
fail ArgumentError, 'You have to provide a base url.' unless base_url
|
39
|
+
base_url
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate_client_secret( client_secret )
|
43
|
+
client_secret ||= ENV['FORTNOX_API_CLIENT_SECRET']
|
44
|
+
fail ArgumentError, 'You have to provide your client secret.' unless client_secret
|
45
|
+
client_secret
|
46
|
+
end
|
47
|
+
|
48
|
+
def validate_access_token( access_token )
|
49
|
+
access_token ||= ENV['FORTNOX_API_ACCESS_TOKEN']
|
50
|
+
fail ArgumentError, 'You have to provide your access token.' unless access_token
|
51
|
+
access_token
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate_authorization_code( authorization_code )
|
55
|
+
authorization_code ||= ENV['FORTNOX_API_AUTHORIZATION_CODE']
|
56
|
+
fail ArgumentError, 'You have to provide your access token.' unless authorization_code
|
57
|
+
authorization_code
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "fortnox/api/customer/repository"
|
2
|
+
require "fortnox/api/customer/validator"
|
3
|
+
require "fortnox/api/customer/entity"
|
4
|
+
|
5
|
+
module Fortnox
|
6
|
+
module API
|
7
|
+
module Customer
|
8
|
+
|
9
|
+
def self.new( hash = {} )
|
10
|
+
Entity.new( hash )
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require "fortnox/api/entity"
|
2
|
+
|
3
|
+
module Fortnox
|
4
|
+
module API
|
5
|
+
module Customer
|
6
|
+
class Entity < Fortnox::API::Entity
|
7
|
+
|
8
|
+
#Url Direct URL to the record
|
9
|
+
attribute :url, String, writer: :private
|
10
|
+
|
11
|
+
#Address1 First address of the customer
|
12
|
+
attribute :address1, String
|
13
|
+
|
14
|
+
#Address2 Second address of the customer
|
15
|
+
attribute :address2, String
|
16
|
+
|
17
|
+
#City City of the customer
|
18
|
+
attribute :city, String
|
19
|
+
|
20
|
+
#Country Country of the customer
|
21
|
+
attribute :country, String
|
22
|
+
|
23
|
+
#Comments Comments
|
24
|
+
attribute :comments, String
|
25
|
+
|
26
|
+
#Currency Currency of the customer, 3 letters
|
27
|
+
attribute :currency, String
|
28
|
+
|
29
|
+
#CostCenter Cost center of the customer, Cost center in Fortnox
|
30
|
+
attribute :cost_center, String
|
31
|
+
|
32
|
+
#CountryCode Country code of the customer, 2 letters
|
33
|
+
attribute :country_code, String
|
34
|
+
|
35
|
+
#CustomerNumber Customer number
|
36
|
+
attribute :customer_number, String
|
37
|
+
|
38
|
+
#DeliveryAddress1 First delivery address of the customer
|
39
|
+
attribute :delivery_address1, String
|
40
|
+
|
41
|
+
#DeliveryAddress2 Second delivery address of the customer
|
42
|
+
attribute :delivery_address2, String
|
43
|
+
|
44
|
+
#DeliveryCity Delivery city of the customer
|
45
|
+
attribute :delivery_city, String
|
46
|
+
|
47
|
+
#DeliveryCountry Delivery country of the customer
|
48
|
+
attribute :delivery_country, String
|
49
|
+
|
50
|
+
#DeliveryCountryCode Delivery country code of the customer
|
51
|
+
attribute :delivery_country_code, String
|
52
|
+
|
53
|
+
#DeliveryFax Delivery fax number of the customer
|
54
|
+
attribute :delivery_fax, String
|
55
|
+
|
56
|
+
#DeliveryName Delivery name of the customer
|
57
|
+
attribute :delivery_name, String
|
58
|
+
|
59
|
+
#DeliveryPhone1 First delivery phone number of the customer
|
60
|
+
attribute :delivery_phone1, String
|
61
|
+
|
62
|
+
#DeliveryPhone2 Second delivery phone number of the customer
|
63
|
+
attribute :delivery_phone2, String
|
64
|
+
|
65
|
+
#DeliveryZipCode Delivery zip code of the customer
|
66
|
+
attribute :delivery_zip_code, String
|
67
|
+
|
68
|
+
#Email Email address of the customer
|
69
|
+
attribute :email, String
|
70
|
+
|
71
|
+
#EmailInvoice Invoice email address of the customer
|
72
|
+
attribute :email_invoice, String
|
73
|
+
|
74
|
+
#EmailInvoiceBCC Invoice BCC email address of the customer
|
75
|
+
attribute :email_invoice_bcc, String
|
76
|
+
|
77
|
+
#EmailInvoiceCC Invoice CC email address of the customer
|
78
|
+
attribute :email_invoice_cc, String
|
79
|
+
|
80
|
+
#EmailOffer Offer email address of the customer
|
81
|
+
attribute :email_offer, String
|
82
|
+
|
83
|
+
#EmailOfferBCC Offer BCC email address of the customer
|
84
|
+
attribute :email_offer_bcc, String
|
85
|
+
|
86
|
+
#EmailOfferCC Offer CC email address of the customer
|
87
|
+
attribute :email_offer_cc, String
|
88
|
+
|
89
|
+
#EmailOrder Order email address of the customer
|
90
|
+
attribute :email_order, String
|
91
|
+
|
92
|
+
#EmailOrderBCC Order BCC email address of the customer
|
93
|
+
attribute :email_order_bcc, String
|
94
|
+
|
95
|
+
#EmailOrderCC Order CC email address of the customer
|
96
|
+
attribute :email_order_cc, String
|
97
|
+
|
98
|
+
#Fax Fax number of the customer
|
99
|
+
attribute :fax, String
|
100
|
+
|
101
|
+
#InvoiceAdministrationFee Invoice administration fee of the customer
|
102
|
+
attribute :invoice_administration_fee, Float
|
103
|
+
|
104
|
+
#InvoiceDiscount Invoice discount of the customer
|
105
|
+
attribute :invoice_discount, Float
|
106
|
+
|
107
|
+
#InvoiceFreight Invoice freight fee of the customer
|
108
|
+
attribute :invoice_freight, Float
|
109
|
+
|
110
|
+
#InvoiceRemark Invoice remark of the customer
|
111
|
+
attribute :invoice_remark, String
|
112
|
+
|
113
|
+
#Name Name of the customer
|
114
|
+
attribute :name, String
|
115
|
+
|
116
|
+
#OrganisationNumber Organisation number of the customer
|
117
|
+
attribute :organisation_number, String
|
118
|
+
|
119
|
+
#OurReference Our reference of the customer
|
120
|
+
attribute :our_reference, String
|
121
|
+
|
122
|
+
#Phone1 First phone number of the customer
|
123
|
+
attribute :phone1, String
|
124
|
+
|
125
|
+
#Phone2 Second phone number of the customer
|
126
|
+
attribute :phone2, String
|
127
|
+
|
128
|
+
#PriceList Price list of the customer, Price list in Fortnox
|
129
|
+
attribute :price_list, String
|
130
|
+
|
131
|
+
#Project Project of the customer, Project in Fortnox
|
132
|
+
attribute :project, Integer
|
133
|
+
|
134
|
+
#SalesAccount Sales account of the customer, 4 digits
|
135
|
+
attribute :sales_account, Integer
|
136
|
+
|
137
|
+
#ShowPriceVATIncluded Show prices with VAT included or not
|
138
|
+
attribute :show_price_vat_included, Boolean
|
139
|
+
|
140
|
+
#TermsOfDeliveryCode Terms of delivery code of the customer
|
141
|
+
attribute :terms_of_delivery_code, String
|
142
|
+
|
143
|
+
#TermsOfPaymentCode Terms of payment code of the customer
|
144
|
+
attribute :terms_of_payment_code, String
|
145
|
+
|
146
|
+
#Type Customer type, PRIVATE / COMPANY
|
147
|
+
attribute :type, String
|
148
|
+
|
149
|
+
#VATNumber VAT number of the customer
|
150
|
+
attribute :vat_number, String
|
151
|
+
|
152
|
+
#VATType VAT type of the customer, SEVAT / SEREVERSEDVAT / EUREVERSEDVAT / EUVAT / EXPORT
|
153
|
+
attribute :vat_type, String
|
154
|
+
|
155
|
+
#VisitAddress Visit address of the customer
|
156
|
+
attribute :visit_address, String
|
157
|
+
|
158
|
+
#VisitCity Visit city of the customer
|
159
|
+
attribute :visit_city, String
|
160
|
+
|
161
|
+
#VisitCountry Visit country of the customer
|
162
|
+
attribute :visit_country, String
|
163
|
+
|
164
|
+
#VisitZipCode Visit zip code of the customer
|
165
|
+
attribute :visit_zip_code, String
|
166
|
+
|
167
|
+
#WayOfDeliveryCode Way of delivery code of the customer
|
168
|
+
attribute :way_of_delivery_code, String
|
169
|
+
|
170
|
+
#YourReference Your reference of the customer
|
171
|
+
attribute :your_reference, String
|
172
|
+
|
173
|
+
#ZipCode Zip code of the customer
|
174
|
+
attribute :zip_code, String
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "fortnox/api/repository/base"
|
2
|
+
|
3
|
+
module Fortnox
|
4
|
+
module API
|
5
|
+
module Customer
|
6
|
+
class Repository < Fortnox::API::Repository::Base
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super(
|
10
|
+
base_uri: '/customers/',
|
11
|
+
json_list_wrapper: 'Customers',
|
12
|
+
json_unit_wrapper: 'Customer',
|
13
|
+
key_map: {
|
14
|
+
vat_type: "VATType",
|
15
|
+
}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def instansiate( hash )
|
22
|
+
Fortnox::API::Customer::Entity.new( hash )
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "fortnox/api/validator"
|
2
|
+
|
3
|
+
module Fortnox
|
4
|
+
module API
|
5
|
+
module Customer
|
6
|
+
class Validator
|
7
|
+
|
8
|
+
extend Fortnox::API::Validator
|
9
|
+
|
10
|
+
using_validations do
|
11
|
+
|
12
|
+
validates_presence_of :name
|
13
|
+
|
14
|
+
validates_length_of :currency, length: 3, if: :currency
|
15
|
+
validates_length_of :country_code, length: 2, if: :country_code
|
16
|
+
|
17
|
+
validates_inclusion_of :sales_account, within: (0..9999), if: :sales_account
|
18
|
+
validates_inclusion_of :type, within: ['PRIVATE', 'COMPANY'], if: :type
|
19
|
+
validates_inclusion_of :vat_type, within: ['SEVAT', 'SEREVERSEDVAT', 'EUREVERSEDVAT', 'EUVAT', 'EXPORT'], if: :vat_type
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "virtus"
|
2
|
+
require "ice_nine"
|
3
|
+
|
4
|
+
module Fortnox
|
5
|
+
module API
|
6
|
+
class Entity
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
include Virtus.model
|
10
|
+
|
11
|
+
attr_accessor :unsaved
|
12
|
+
|
13
|
+
def initialize( hash = {} )
|
14
|
+
@unsaved = hash.delete( :unsaved ){ true }
|
15
|
+
super
|
16
|
+
IceNine.deep_freeze( self )
|
17
|
+
end
|
18
|
+
|
19
|
+
def update( hash )
|
20
|
+
attributes = self.to_hash.merge( hash )
|
21
|
+
|
22
|
+
return self if attributes == self.to_hash
|
23
|
+
|
24
|
+
self.class.new( attributes )
|
25
|
+
end
|
26
|
+
|
27
|
+
# Generic comparison, by value, use .eql? or .equal? for object identity.
|
28
|
+
def ==( other )
|
29
|
+
return false unless other.is_a? self.class
|
30
|
+
self.to_hash == other.to_hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_json
|
34
|
+
hash = attribute_set.each_with_object({}) do |attribute, hash|
|
35
|
+
name = attribute.options[ :name ]
|
36
|
+
key = attribute.options[ :json_name ] || attribute_name_to_json( name )
|
37
|
+
value = attributes[name]
|
38
|
+
hash[ key ] = value
|
39
|
+
end
|
40
|
+
hash.to_json
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "fortnox/api/base"
|
2
|
+
require "fortnox/api/repository/json_convertion"
|
3
|
+
require "fortnox/api/repository/loaders"
|
4
|
+
require "fortnox/api/repository/savers"
|
5
|
+
|
6
|
+
module Fortnox
|
7
|
+
module API
|
8
|
+
module Repository
|
9
|
+
class Base < Fortnox::API::Base
|
10
|
+
|
11
|
+
include JSONConvertion
|
12
|
+
include Loaders
|
13
|
+
include Savers
|
14
|
+
|
15
|
+
def initialize( options = {} )
|
16
|
+
super()
|
17
|
+
@base_uri = options.fetch( :base_uri ){ '/' }
|
18
|
+
@json_list_wrapper = options.fetch( :json_list_wrapper ){ '' }
|
19
|
+
@json_unit_wrapper = options.fetch( :json_unit_wrapper ){ '' }
|
20
|
+
@attr_to_json_map = options.fetch( :key_map ){ {} }
|
21
|
+
@json_to_attr_map = @attr_to_json_map.invert
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fortnox
|
2
|
+
module API
|
3
|
+
module Repository
|
4
|
+
module JSONConvertion
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def hash_to_entity( entity_json_hash )
|
9
|
+
entity_hash = convert_hash_keys_from_json_format( entity_json_hash )
|
10
|
+
instansiate( entity_hash )
|
11
|
+
end
|
12
|
+
|
13
|
+
def entity_to_hash( entity )
|
14
|
+
entity_hash = entity.to_hash
|
15
|
+
entity_json_hash = convert_hash_keys_to_json_format( entity_hash )
|
16
|
+
{ @json_unit_wrapper => entity_json_hash }
|
17
|
+
end
|
18
|
+
|
19
|
+
def convert_hash_keys_from_json_format( hash )
|
20
|
+
hash.each_with_object( {} ) do |(key, value), json_hash|
|
21
|
+
json_hash[ convert_key_from_json( key ) ] = value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def convert_key_from_json( key )
|
26
|
+
@json_to_attr_map.fetch( key ){ default_key_from_json_transform( key ) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_key_from_json_transform( key )
|
30
|
+
key = key.to_s
|
31
|
+
return key.downcase if key.match(/\A[A-Z]+\z/)
|
32
|
+
key.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
33
|
+
gsub(/([a-z])([A-Z])/, '\1_\2').
|
34
|
+
downcase.
|
35
|
+
to_sym
|
36
|
+
end
|
37
|
+
|
38
|
+
def convert_hash_keys_to_json_format( hash )
|
39
|
+
hash.each_with_object( {} ) do |key, value, json_hash|
|
40
|
+
json_hash[ convert_key_to_json( key ) ] = value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def convert_key_to_json( key )
|
45
|
+
@attr_to_json_map.fetch( key ){ default_key_to_json_transform( key ) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_key_to_json_transform( key )
|
49
|
+
key.to_s.split('_').map(&:capitalize).join('')
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|