fortnox-api 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +18 -0
  3. data/.gitignore +6 -1
  4. data/.rubocop.yml +1107 -0
  5. data/.travis.yml +9 -3
  6. data/CONTRIBUTE.md +26 -0
  7. data/Gemfile +0 -0
  8. data/Guardfile +2 -2
  9. data/LICENSE.txt +0 -0
  10. data/README.md +109 -88
  11. data/Rakefile +0 -0
  12. data/docs/account.rb +59 -0
  13. data/docs/extraction_script.js +23 -0
  14. data/docs/generation_script.rb +43 -0
  15. data/docs/json/account.json +77 -0
  16. data/fortnox-api.gemspec +4 -1
  17. data/lib/fortnox/api.rb +14 -3
  18. data/lib/fortnox/api/base.rb +25 -36
  19. data/lib/fortnox/api/class_methods.rb +13 -45
  20. data/lib/fortnox/api/environment_validation.rb +33 -0
  21. data/lib/fortnox/api/models.rb +1 -0
  22. data/lib/fortnox/api/models/attributes/country_code.rb +17 -0
  23. data/lib/fortnox/api/models/attributes/currency.rb +17 -0
  24. data/lib/fortnox/api/models/base.rb +67 -0
  25. data/lib/fortnox/api/{customer/entity.rb → models/customer.rb} +31 -12
  26. data/lib/fortnox/api/models/edi_information.rb +28 -0
  27. data/lib/fortnox/api/models/email_information.rb +25 -0
  28. data/lib/fortnox/api/models/invoice.rb +253 -0
  29. data/lib/fortnox/api/models/row.rb +82 -0
  30. data/lib/fortnox/api/repositories.rb +1 -0
  31. data/lib/fortnox/api/repositories/base.rb +34 -0
  32. data/lib/fortnox/api/{repository → repositories/base}/json_convertion.rb +18 -5
  33. data/lib/fortnox/api/{repository → repositories/base}/loaders.rb +16 -8
  34. data/lib/fortnox/api/repositories/base/options.rb +33 -0
  35. data/lib/fortnox/api/repositories/base/savers.rb +39 -0
  36. data/lib/fortnox/api/repositories/customer.rb +38 -0
  37. data/lib/fortnox/api/repositories/invoice.rb +35 -0
  38. data/lib/fortnox/api/request_handling.rb +35 -0
  39. data/lib/fortnox/api/validators.rb +1 -0
  40. data/lib/fortnox/api/validators/attributes/country_code.rb +42 -0
  41. data/lib/fortnox/api/validators/attributes/currency.rb +38 -0
  42. data/lib/fortnox/api/validators/base.rb +70 -0
  43. data/lib/fortnox/api/validators/constant.rb +21 -0
  44. data/lib/fortnox/api/validators/customer.rb +29 -0
  45. data/lib/fortnox/api/validators/edi_information.rb +11 -0
  46. data/lib/fortnox/api/validators/email_information.rb +19 -0
  47. data/lib/fortnox/api/validators/invoice.rb +33 -0
  48. data/lib/fortnox/api/validators/row.rb +22 -0
  49. data/lib/fortnox/api/version.rb +1 -1
  50. data/spec/fortnox/api/base_spec.rb +65 -62
  51. data/spec/fortnox/api/models/attributes/country_code_spec.rb +23 -0
  52. data/spec/fortnox/api/models/attributes/currency_spec.rb +23 -0
  53. data/spec/fortnox/api/models/attributes/dummy_model_context.rb +9 -0
  54. data/spec/fortnox/api/models/base_spec.rb +76 -0
  55. data/spec/fortnox/api/models/invoice_spec.rb +36 -0
  56. data/spec/fortnox/api/models/row_spec.rb +13 -0
  57. data/spec/fortnox/api/repositories/context.rb +10 -0
  58. data/spec/fortnox/api/repositories/customer_spec.rb +85 -0
  59. data/spec/fortnox/api/repositories/examples.rb +16 -0
  60. data/spec/fortnox/api/repositories/invoice_spec.rb +10 -0
  61. data/spec/fortnox/api/validators/attributes/country_code_spec.rb +9 -0
  62. data/spec/fortnox/api/validators/attributes/currency_spec.rb +9 -0
  63. data/spec/fortnox/api/validators/attributes/examples_for_validate.rb +29 -0
  64. data/spec/fortnox/api/validators/base_spec.rb +61 -0
  65. data/spec/fortnox/api/validators/constant_spec.rb +12 -0
  66. data/spec/fortnox/api/validators/context.rb +102 -0
  67. data/spec/fortnox/api/validators/customer_spec.rb +31 -0
  68. data/spec/fortnox/api/validators/edi_information_spec.rb +18 -0
  69. data/spec/fortnox/api/validators/email_information_spec.rb +26 -0
  70. data/spec/fortnox/api/validators/invoice_spec.rb +36 -0
  71. data/spec/fortnox/api/validators/row_spec.rb +27 -0
  72. data/spec/fortnox/api/validators/validator_examples.rb +20 -0
  73. data/spec/fortnox/api_spec.rb +36 -0
  74. data/spec/spec_helper.rb +16 -4
  75. data/spec/support/helpers.rb +1 -0
  76. data/spec/support/helpers/dummy_class_helper.rb +20 -0
  77. data/spec/support/matchers.rb +1 -0
  78. data/spec/support/matchers/models.rb +27 -0
  79. data/spec/support/matchers/validators.rb +36 -0
  80. data/spec/support/vcr_setup.rb +6 -0
  81. data/spec/vcr_cassettes/customers/all.yml +47 -0
  82. data/spec/vcr_cassettes/customers/find_id_1.yml +47 -0
  83. data/spec/vcr_cassettes/customers/save_new.yml +47 -0
  84. data/spec/vcr_cassettes/customers/save_old.yml +49 -0
  85. metadata +133 -21
  86. data/.ruby-version +0 -1
  87. data/Gemfile.lock +0 -127
  88. data/lib/fortnox/api/customer.rb +0 -15
  89. data/lib/fortnox/api/customer/repository.rb +0 -28
  90. data/lib/fortnox/api/customer/validator.rb +0 -26
  91. data/lib/fortnox/api/entity.rb +0 -45
  92. data/lib/fortnox/api/repository/base.rb +0 -27
  93. data/lib/fortnox/api/repository/savers.rb +0 -15
  94. data/lib/fortnox/api/validator.rb +0 -32
  95. data/spec/fortnox/api/customer/repository_spec.rb +0 -0
  96. data/spec/fortnox/api/customer/validator_spec.rb +0 -32
  97. data/spec/fortnox/api/entity_spec.rb +0 -62
data/.travis.yml CHANGED
@@ -1,4 +1,10 @@
1
1
  rvm:
2
- - "2.0.0"
3
- - "2.1.6"
4
- - "2.2.2"
2
+ - "2.1.8"
3
+ - "2.2.4"
4
+ - "2.3.0"
5
+ addons:
6
+ code_climate:
7
+ repo_token: 397c19af63ca3467cff6fd640b0460b691f687118332b5989f530d28f82adcb8
8
+ notifications:
9
+ slack: my-codeworks:fwKO4YfipnmNKJQL3cRSEoKB
10
+ email: false
data/CONTRIBUTE.md ADDED
@@ -0,0 +1,26 @@
1
+ 1. Fork it ( http://github.com/my-codeworks/fortnox-api/fork )
2
+ 2. Clone your fork (`git clone https://github.com/<your GitHub user
3
+ name>/fortnox-api.git`)
4
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
5
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
6
+ 5. Push to the branch (`git push origin my-new-feature`)
7
+ 6. Create new Pull Request
8
+
9
+ ### Adding upstream remote
10
+
11
+ If you want to keep contributing, it is a good idea to add the original repo as
12
+ remote server to your clone ( `git remote add upstream
13
+ https://github.com/my-codeworks/fortnox-api` ). Then you can do something like
14
+ this to update your fork:
15
+
16
+ 1. Fetch branches from upstream (`git fetch upstream`)
17
+ 2. Checkout your master branch (`git checkout master`)
18
+ 3. Update it (`git rebase upstream/master`)
19
+ 4. And push it to your fork (`git push origin master`)
20
+
21
+ If you want to update another branch:
22
+ ```
23
+ git checkout branch-name
24
+ git rebase upstream/branch-name
25
+ git push origin branch-name
26
+ ```
data/Gemfile CHANGED
File without changes
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
1
  guard :rspec, cmd: 'bundle exec rspec --color', all_after_pass: true do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
- watch('spec/spec_helper.rb') { "spec" }
3
+ watch(%r{^lib/(.+)\.rb$}){ |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb'){ "spec" }
5
5
  end
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -1,33 +1,84 @@
1
- # Fortnox::API
2
-
3
- Wrapper gem for Fortnox AB's version 3 API.
1
+ # Fortnox API
2
+ > Wrapper gem for Fortnox AB's version 3 REST(ish) API. If you need to integrate an existing or new Ruby or Rails app against Fortnox this gem will save you a lot of time, you are welcome. Feel free to repay the community with some nice PRs of your own :simple_smile:
4
3
 
4
+ # Status
5
5
  [![Gem Version](https://badge.fury.io/rb/fortnox-api.png)](http://badge.fury.io/rb/fortnox-api)
6
6
  [![Build Status](https://travis-ci.org/my-codeworks/fortnox-api.png)](https://travis-ci.org/my-codeworks/fortnox-api)
7
7
  [![Code Climate](https://codeclimate.com/github/my-codeworks/fortnox-api.png)](https://codeclimate.com/github/my-codeworks/fortnox-api)
8
+ [![Test Coverage](https://codeclimate.com/github/my-codeworks/fortnox-api/badges/coverage.svg)](https://codeclimate.com/github/my-codeworks/fortnox-api/coverage)
8
9
  [![Dependency Status](https://gemnasium.com/my-codeworks/fortnox-api.svg)](https://gemnasium.com/my-codeworks/fortnox-api)
9
10
 
10
- ## Features
11
+ The rough status of this project is as follows (as of Marsh 2016):
12
+ * In active development (just check out the commit log)
13
+ * Two developers. At least twice as good as one.
14
+ * Basic structure mostly complete. Things like getting customers and invoices, updating and saving etc.
15
+ * Advanced features around the corner. Things like filtering entities or sorting, pagination of results etc.
16
+ * A few models implemented. Right now it's Customer and Invoice that are the furthest along. Order and Offer will be done quickly once Invoice is completed and adding more models in general is quick and easy, see the developer guid further down.
17
+ * Massive refactorings of the code occurs weakly :) This is not at all stable for production yet.
18
+
19
+ The goal is to have a production ready version that covers at least the Invoice, Order, Offer, Customer, Account and Bookkeeping models by July or August.
20
+
21
+ # Architecture overview
22
+ The gem is structured with three distinct models for the tasks of data, validation and saving state. These are, as is traditional, called: model, validator and repository.
23
+
24
+ If you come from a Rails background and have not been exposed to other ways of structuring the solution to the CRUD problem this might seem strange to you since ActiveRecord merges these three roles into the `ActiveRecord::Base` class.
25
+
26
+ To keep it simple: The active record pattern (as implemented by Rails) is easier to work with if you only have one data source, the database, in your application. The data mapper pattern is easier to work with if you have several data sources, such ass different databases, external APIs and flat files on disk etc, in your application. It's also easier to compose the data mapper components into active record like classes than to separate active records parts to get a data mapper style structure.
27
+
28
+ If you are interested in a more detailed description of the difference between the two architectures you can read this post that explains it well using simple examples: [What’s the difference between Active Record and Data Mapper?](http://culttt.com/2014/06/18/whats-difference-active-record-data-mapper/)
29
+
30
+ ## Model
31
+ The model role classes serve as dumb data objects. They do have some logic to coheres values etc, but they do not contain validation logic nor any business logic at all.
32
+
33
+ ### Attribute
34
+ Several of the models share attributes. One example is account, as in a bookkeeping account number. These attributes have the same definition, cohesion and validation logic so it makes sense to extract them from the models and put them in separate classes.
35
+
36
+ You can find several of these under the `/models/attributes` directory where the implementation of the definition and cohesion lives. For the validation part see Validator below.
11
37
 
12
- Quick overview of the current status of this gem vs the API it integrates
13
- against:
38
+ ### Immutability
39
+ The model instances are immutable. That means:
40
+ ```ruby
41
+ customer.name # => "Old Name"
42
+ customer.name = 'New Name' # => "New Name"
43
+
44
+ customer.name == "New Name" # => false
45
+ ```
46
+ Normally you would expect an assignment to mutate the instance and update the `name` field. Immutability explicitly means that you can't mutate state this way, any operation that attempts to update state needs to return a new instance with the updated state while leaving the old instance alone.
14
47
 
15
- API resource | Status
16
- ------------------------------------------ | --------
17
- Exchange AuthorizationCode for AccessToken | :white_check_mark:
18
- Entity base class with immutability | :white_check_mark:
19
- Validator base class based on Vanguard | :white_check_mark:
20
- Customer::Validator | :white_check_mark:
21
- Customers | :hourglass:
22
- Repository READ from API functionality | :hourglass:
48
+ So you might think you should do this instead:
49
+ ```ruby
50
+ customer = customer.name = 'New Name' # => "New Name"
51
+ ```
52
+ But if you are familiar with chaining assignments in Ruby you will see that this does not work. The result of any assignment, `LHS = RHS`, operation in Ruby is `RHS`. Even if you implement your own `=` method and explicitly return something else. This is a feature of the language and not something we can get around. So instead you have to do:
53
+ ```ruby
54
+ customer.name # => "Old Name"
55
+ customer = customer.update( name: 'New Name' ) # => <Fortnox::API::Customer:0x007fdf22949298 ... >
56
+ customer.name == "New Name" # => true
57
+ ```
58
+ And note that:
59
+ ```ruby
60
+ customer.name # => "Old Name"
61
+ customer.update( name: 'New Name' ) # => <Fortnox::API::Customer:0x007fdf21100b00 ... >
62
+ customer.name == "New Name" # => false
63
+ ```
64
+ This is how all the models work, they are all immutable.
65
+ ## Validator
66
+ The validators enforce the constraints on values, lengths and, in some cases, content of the model attributes. You should run the validator on the model before trying to persist it using the repository. You can send any model instance off to the repository and you will get errors back from Fortnox's API server, but using the validator you get a nice list of errors that you can present to the end user instead of pinging the API once for every error and rescuing the exception we throw when we get a 4xx/5xx response from the server.
23
67
 
24
- ## Requirements
68
+ ### Attribute
69
+ As the model separates some attributes out into separate classes it makes sense that the validators for these models are similarly composable. The attribute validators can be found in `/validators/attributes` and each match one of the model attributes.
25
70
 
26
- This gem is build for Ruby 2.0 or higher, it's tested agains Ruby 2.0.0 and
27
- 2.1.2. Since it uses the keywords argument feature it won't work on Ruby 1.9.
71
+ ## Repositories
72
+ Used to load, update, create and delete model instances. This is what's actually wrapping the HTTP REST API actions.
28
73
 
29
- If you want or need Ruby 1.9 compatability please contact us or better yet,
30
- submit a pull request. Instructions are to be found below :)
74
+ # Requirements
75
+
76
+ This gem is build for Ruby 2.0 or higher, it's tested agains Ruby 2.1.8, 2.2.4
77
+ and 2.3.0. Since it uses the keywords argument feature it won't work on older
78
+ versions.
79
+
80
+ If you want or need Ruby 1.9 compatibility please submit a pull request.
81
+ Instructions can be found below :)
31
82
 
32
83
  ## Installation
33
84
 
@@ -49,105 +100,75 @@ Or install it yourself as:
49
100
  $ gem install fortnox-api
50
101
  ```
51
102
 
52
- ## Usage
103
+ # Usage
53
104
 
54
- ### Getting an AccessToken
105
+ ## Getting an AccessToken
106
+ To make calls to the API server you need a `ClientSecret` and an `AccessToken`. When you sign up for an API-account with Fortnox you should get a client secret and an authorization code. To get the access token, that is reusable, you need to do a one time exchange with the API-server and exchange your authorization code for an access token. This can be done in several ways but we provide a method for it in the gem that you can use.
55
107
 
56
- Unless you have an AccessToken already you will need to exchange your
57
- AuthorizationCode for one to make calls. In a ruby shell do the following
108
+ > :warning: **Do not do this more than once!** If you try to do the auth code/access token exchange more than once, regardless of method, it will lock your API-account! So if you get the token using curl or whatever do not use this method as well. If your account is not working and you think it might be due to this you will have to contact Fortnox support and have them reset the authorization code for you.
58
109
 
59
110
  ```ruby
60
- require 'fortnox-api' # Load the gem, it needs to be installed first
61
- Fortnox::API.get_access_token(
111
+ # Load the special class from the gem. You need to install the gem first ofc.
112
+ require 'fortnox/api/access_token'
113
+
114
+ Fortnox::API::AccessToken.new(
62
115
  base_url: 'https://api.fortnox.se/3',
63
- client_secret: 'P5K5wE3Kun',
64
- authorization_code: 'ea3862b1-189c-464b-8e25-1b9702365fa1',
116
+ client_secret: 'P5K5wE3Kun', # Replace with your client secret
117
+ authorization_code: 'ea3862b1-189c-464b-8e25-1b9702365fa1', # Replace with your auth code
65
118
  )
66
119
  ```
120
+ This will output a new token like `3f08d038-f380-4893-94a0a0-8f6e60e67a` that is your access token, **save it!** Set it in the environment by following the instructions in the next step.
67
121
 
68
- This will output a new token like `3f08d038-f380-4893-94a0a0-8f6e60e67a` that is
69
- your access token, **save it!** You will need to save it since it will be used
70
- every time you instansiate a Fortnox::API object.
122
+ ## Environment variables
123
+ The authentication for this gem is stored in the environment. See the documentation for your OS to get instructions for how to set environment variables in it.
71
124
 
72
- ### Using environment variables
125
+ You can choose to use the [`dotenv` gem](https://github.com/bkeepers/dotenv) that we include for development but it is NOT recommended to use in production. You should set proper environment variables in production so you don't have to commit the environment file to source control.
73
126
 
74
- You can save your settings in environment variables that will be used by the gem
75
- when you instantiate it. The following variables are recognized:
76
-
77
- ```
78
- FORTNOX_API_BASE_URL
127
+ The environment variables we use are:
128
+ ```bash
79
129
  FORTNOX_API_CLIENT_SECRET
80
130
  FORTNOX_API_ACCESS_TOKEN
81
- FORTNOX_API_AUTHORIZATION_CODE
82
131
  ```
132
+ Their values should match their name.
83
133
 
84
- Their values should match their name. Note that the authorization code is only
85
- ever used once and only when you call the `get_access_token` method described
86
- above.
87
-
88
- ### Collections
89
-
90
- To get something to work with you instantiate a new Fortnox::API object
134
+ # Usage
135
+ ## Repositories
136
+ Repositories are used to load,save and remove entities from the remote server. The calls are subject to network latency and are blocking. Do make sure to rescue appropriate network errors in your code.
91
137
 
92
138
  ```ruby
93
- fortnox = Fortnox::API.new(
94
- base_url: 'https://api.fortnox.se/3',
95
- client_secret: 'P5K5wE3Kun',
96
- access_token: '3f08d038-f380-4893-94a0a0-8f6e60e67a',
97
- )
98
- ```
99
-
100
- On this you can then call things like
101
-
102
- ```ruby
103
- # Get a list of all the customers (slow, don't use unless you have to)
104
- fortnox.customer.all #=> [<Fortnox::API::Customer:0x007fdf21033ee8>, <Fortnox::API::Customer:0x007fdf22994310>, ... ]
139
+ # Instanciate a repository
140
+ repo = Fortnox::API::Repository::Customer.new
105
141
 
106
- # Get single customer by id
107
- fortnox.customer.find( 5 ) #=> <Fortnox::API::Customer:0x007fdf21100b00>
142
+ # Get a list of all the entities
143
+ repo.all #=> <Fortnox::API::Collection:0x007fdf2104575638 @entities: [<Fortnox::API::Customer::Simple:0x007fdf21033ee8>, <Fortnox::API::Customer::Simple:0x007fdf22994310>, ... ]
108
144
 
109
- # Get single customer by customer number
110
- fortnox.customer.find_by( customer_number: 5 ) #=> <Fortnox::API::Customer:0x007fdf22949298>
145
+ # Get entity by id
146
+ repo.find( 5 ) #=> <Fortnox::API::Customer:0x007fdf21100b00>
111
147
 
112
- # Get all customers matching some criteria
113
- fortnox.customer.find_all_by( name: 'test' ) #=> [<Fortnox::API::Customer:0x007fdf22949298>, ... ]
148
+ # Get entities by attribute
149
+ repo.find_by( customer_number: 5 ) #=> <Fortnox::API::Collection:0x007fdf22994310 @entities: [<Fortnox::API::Customer::Simple:0x007fdf22949298>]
114
150
  ```
151
+ If you are eagle eyed you might have spotted the different classes for the entities returned in a collection vs the one we get from find. The `Simple` version of a class is used in thouse cases where the API-server doesn't return a full set of attributes for an entity. For customers the simple version has 10 attributes while the full have over 40.
115
152
 
116
- ### Entities
153
+ You should try to get by using the simple versions for as long as possible. Both the `Collection` and `Simple` classes have a `.full` method that will give you full versions of the entities. Bare in mind though that a collection of 20 simple models that you run `.full` on will call out to the server 20 times, in sequence.
117
154
 
118
- All the above methods return instances or arrays of instances of some resource
155
+ ## Entities
156
+ All the repository methods return instances or collections of instances of some resource
119
157
  class such as customer, invoice, item, voucher and so on.
120
158
 
121
159
  Instances are immutable and any update returns a new instance with the
122
- appropriate attributes changed.
123
-
124
- > :warning: Ruby implements assignment statements so that `LHS = RHS`
125
- > always returns `RHS`. This is regardless of what an assignment method is
126
- > implemented to return.
127
- >
128
- > This means that assignments like `customer.name = 'Test'` will return
129
- > `'Test'` and not a new instance of `Customer`, which is what you want in this
130
- > case. So assignment methods to update objects is not possible. Use the
131
- > `.update()` method instead.
132
-
133
- Each entity class has it's own methods and properties but they also all respond
134
- to a few common methods, such as for persistence.
160
+ appropriate attributes changed (see the Immutable section under Architecture above for more details). To change the properties of a model works like this:
135
161
 
136
162
  ```ruby
137
163
  customer #=> <Fortnox::API::Customer:0x007fdf228db310>
138
164
  customer.name #=> "Nelly Bloom"
139
165
  customer.update( name: "Ned Stark" ) #=> <Fortnox::API::Customer:0x0193a456ff0307>
140
166
  customer.name #=> "Nelly Bloom"
141
- updated_customer = customer.update( name: "Ned Stark" )
142
- updated_customer.name #=> "Nelly Bloom"
143
- updated_customer.save #=> true on success or false on failure
144
- updated_customer.save! #=> true on success or raises Fortnox::API::RequestFailed exception on failure
145
- ```
146
167
 
147
- ## Contributing
168
+ updated_customer = customer.update( name: "Ned Stark" ) #=> <Fortnox::API::Customer:0x0193a456fe3791>
169
+ updated_customer.name #=> "Ned Stark"
170
+ ```
148
171
 
149
- 1. Fork it ( http://github.com/my-codeworks/fortnox-api/fork )
150
- 2. Create your feature branch (`git checkout -b my-new-feature`)
151
- 3. Commit your changes (`git commit -am 'Add some feature'`)
152
- 4. Push to the branch (`git push origin my-new-feature`)
153
- 5. Create new Pull Request
172
+ The update method takes an implicit hash of attributes to update, so you can update as many as you like in one go.
173
+ # Contributing
174
+ See the [CONTRIBUTE](CONTRIBUTE.md) readme.
data/Rakefile CHANGED
File without changes
data/docs/account.rb ADDED
@@ -0,0 +1,59 @@
1
+ require "fortnox/api/models/base"
2
+
3
+ module Fortnox
4
+ module API
5
+ module Entities
6
+ module Account
7
+ class Entity < Fortnox::API::Model::Base
8
+
9
+ # Direct URL to the record
10
+ attribute :url, String
11
+
12
+ # If the account is actve
13
+ attribute :acitve, Boolean
14
+
15
+ # Opening balance of the account
16
+ attribute :balancebroughtforward, Float
17
+
18
+ # Closing balance of the account
19
+ attribute :balancecarriedforward, Float
20
+
21
+ # Code of the proposed cost center. The code must be of an existing cost center.
22
+ attribute :costcenter, String
23
+
24
+ # Cost center settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED
25
+ attribute :costcentersettings, String
26
+
27
+ # Account description
28
+ attribute :description, String
29
+
30
+ # Account number
31
+ attribute :number, Integer
32
+
33
+ # Number of the proposed project. The number must be of an existing project.
34
+ attribute :project, Integer
35
+
36
+ # Project settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED
37
+ attribute :projectsettings, String
38
+
39
+ # SRU code
40
+ attribute :sru, String
41
+
42
+ # Proposed transaction information
43
+ attribute :transactioninformation, String
44
+
45
+ # Transaction information settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED
46
+ attribute :transactioninformationsettings, String
47
+
48
+ # VAT code
49
+ attribute :vatcode, String
50
+
51
+ # Id of the financial year.
52
+ attribute :year, Integer
53
+
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,23 @@
1
+ o = {};
2
+
3
+ $('table.target tr').each(function(index, row){
4
+
5
+ first_column = $('td', row).first();
6
+ name = first_column.text().toLowerCase();
7
+
8
+ last_column = $('td', row).last().text();
9
+
10
+ parts = last_column.split(/\n|,/);
11
+ parts = parts.map( function( el ){ return el.trim(); });
12
+
13
+ type = parts.shift();
14
+ description = parts.pop();
15
+ validations = parts.length > 0 ? parts.join(', ') : null;
16
+ o[ name ] = {
17
+ "type": type,
18
+ "validations": validations,
19
+ "description": description
20
+ }
21
+ });
22
+
23
+ JSON.stringify(o);
@@ -0,0 +1,43 @@
1
+ require 'json'
2
+
3
+ filename = 'account.json'
4
+ modelname = filename.split('.').first.capitalize
5
+
6
+ json = File.read( 'json/account.json' )
7
+ hash = JSON.parse( json )
8
+
9
+ header = <<-RB
10
+ require "fortnox/api/models/base"
11
+
12
+ module Fortnox
13
+ module API
14
+ module Entities
15
+ module {{ model_name }}
16
+ class Entity < Fortnox::API::Model::Base
17
+
18
+ RB
19
+
20
+ footer = <<-RB
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ RB
28
+
29
+ attribute = <<-RB
30
+ # {{ description }}
31
+ attribute :{{ name }}, {{ type }}
32
+
33
+ RB
34
+
35
+ generated_class = header.gsub( '{{ model_name }}', modelname )
36
+
37
+ hash.each do |name, attributes|
38
+ generated_class << attribute.gsub( '{{ description }}', attributes.fetch( 'description' ) ).gsub( '{{ name }}', name ).gsub( '{{ type }}', attributes.fetch( 'type' ).capitalize )
39
+ end
40
+
41
+ generated_class << footer
42
+
43
+ File.write( "#{ modelname.downcase }.rb", generated_class )
@@ -0,0 +1,77 @@
1
+ {
2
+ "url": {
3
+ "type": "string",
4
+ "validations": "read-only",
5
+ "description": "Direct URL to the record"
6
+ },
7
+ "acitve": {
8
+ "type": "boolean",
9
+ "validations": null,
10
+ "description": "If the account is actve"
11
+ },
12
+ "balancebroughtforward": {
13
+ "type": "float",
14
+ "validations": null,
15
+ "description": "Opening balance of the account"
16
+ },
17
+ "balancecarriedforward": {
18
+ "type": "float",
19
+ "validations": "read-only",
20
+ "description": "Closing balance of the account"
21
+ },
22
+ "costcenter": {
23
+ "type": "string",
24
+ "validations": null,
25
+ "description": "Code of the proposed cost center. The code must be of an existing cost center."
26
+ },
27
+ "costcentersettings": {
28
+ "type": "string",
29
+ "validations": null,
30
+ "description": "Cost center settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED"
31
+ },
32
+ "description": {
33
+ "type": "string",
34
+ "validations": "200 characters, required",
35
+ "description": "Account description"
36
+ },
37
+ "number": {
38
+ "type": "integer",
39
+ "validations": "4 digits, sortable, required",
40
+ "description": "Account number"
41
+ },
42
+ "project": {
43
+ "type": "integer",
44
+ "validations": null,
45
+ "description": "Number of the proposed project. The number must be of an existing project."
46
+ },
47
+ "projectsettings": {
48
+ "type": "string",
49
+ "validations": null,
50
+ "description": "Project settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED"
51
+ },
52
+ "sru": {
53
+ "type": "string",
54
+ "validations": "4 or 5 digits, searchable",
55
+ "description": "SRU code"
56
+ },
57
+ "transactioninformation": {
58
+ "type": "string",
59
+ "validations": "100 characters",
60
+ "description": "Proposed transaction information"
61
+ },
62
+ "transactioninformationsettings": {
63
+ "type": "string",
64
+ "validations": null,
65
+ "description": "Transaction information settings for the account. Can be ALLOWED MANDATORY or NOTALLOWED"
66
+ },
67
+ "vatcode": {
68
+ "type": "string",
69
+ "validations": null,
70
+ "description": "VAT code"
71
+ },
72
+ "year": {
73
+ "type": "integer",
74
+ "validations": "read-only",
75
+ "description": "Id of the financial year."
76
+ }
77
+ }