fortnox 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ *.swp
7
+ spec/fixtures/cassettes/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fortnox.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,15 @@
1
+ # Fortnox Ruby Wrapper
2
+ Based on HTTParty
3
+ For Invoicing, Customers
4
+
5
+ ## Testing
6
+ * RSpec
7
+ * Fakeweb/VCR?
8
+ * guard start
9
+
10
+ ## Poor mans docs
11
+
12
+ * Som det fungerar nu är det Fortnox::Invoice.create .update .destroy som gäller
13
+ * Du får ett ID tillbaka när det gick bra annars false.
14
+ * ID behövs användas för att exempelvis uppdatera.
15
+ * Värt att notera är att när du lägger till en kontakt på en faktura är det inte ID du får när du skapar en kontakt som gäller, ID då är kundnr.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fortnox/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "fortnox"
7
+ s.version = Fortnox::VERSION
8
+ s.authors = ["Jonas Arnklint", "Kevin Sjöberg"]
9
+ s.email = ["jonas@fkw.se", "kev.sjoberg@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Handle invoices and customers through the Fortnox API}
12
+ s.description = %q{Handle invoices and customers through the Fortnox API}
13
+
14
+ s.rubyforge_project = "fortnox"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "vcr"
23
+ s.add_development_dependency "webmock"
24
+
25
+ s.add_runtime_dependency "httparty"
26
+ s.add_runtime_dependency "gyoku"
27
+ end
@@ -0,0 +1,11 @@
1
+ require "httparty"
2
+ require "gyoku"
3
+
4
+ require "fortnox/version"
5
+ require "fortnox/api"
6
+ require "fortnox/invoice"
7
+ require "fortnox/customer"
8
+ require "fortnox/errors"
9
+
10
+ module Fortnox
11
+ end
@@ -0,0 +1,43 @@
1
+ module Fortnox
2
+ class API
3
+ include HTTParty
4
+
5
+ base_uri 'https://kund2.fortnox.se/ext/'
6
+ format :xml
7
+
8
+ class << self
9
+ def establish_connection(opts={})
10
+ @@token = opts[:token] || ENV['fortnox_token']
11
+ @@database = opts[:database] || ENV['fortnox_database']
12
+ @@query_parameters = connection
13
+ end
14
+
15
+ def connection
16
+ { :token => @@token, :db => @@database }
17
+ end
18
+
19
+ def run(method, call, attributes={})
20
+ self.query_parameters = attributes[:query] if attributes[:query]
21
+ self.send(method, "/#{call.to_s}.php", {
22
+ :query => query_parameters,
23
+ :body => {:xml => build_xml(attributes)}
24
+ })
25
+ end
26
+
27
+ def query_parameters
28
+ @@query_parameters
29
+ end
30
+
31
+ def query_parameters=(params={})
32
+ @@query_parameters = query_parameters.merge(params)
33
+ end
34
+
35
+ private
36
+
37
+ def build_xml(attributes)
38
+ attributes.delete(:query) if attributes[:query]
39
+ @@xml = Gyoku.xml(attributes)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,23 @@
1
+ module Fortnox
2
+ class Customer < API
3
+ class << self
4
+ def create(attributes={})
5
+ attributes = attributes.reject { |k,v| k == :id } if attributes[:id]
6
+
7
+ response = run(:post, :set_contact, with_root(attributes))
8
+ response['result'] ? response['result']['id'].to_i : false
9
+ end
10
+
11
+ def update(attributes={})
12
+ response = run :post, :set_contact, with_root(attributes)
13
+ response['result'] ? response['result']['id'].to_i : false
14
+ end
15
+
16
+ private
17
+
18
+ def with_root(attributes)
19
+ {:contact => attributes}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Fortnox
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,32 @@
1
+ module Fortnox
2
+ class Invoice < API
3
+ class << self
4
+ def create(attributes={})
5
+ attributes = attributes.reject { |k,v| k == :id } if attributes[:id]
6
+
7
+ response = run :post, :set_invoice, with_root(attributes)
8
+ if response['result']
9
+ return response['result']['id'].to_i
10
+ else
11
+ raise Error, response.body
12
+ end
13
+ end
14
+
15
+ def update(attributes={})
16
+ response = run :post, :set_invoice, with_root(attributes)
17
+ response['result'] ? response['result']['id'].to_i : false
18
+ end
19
+
20
+ def destroy(id)
21
+ response = run :post, :set_invoice_cancel, { :query => { :id => id } }
22
+ response['result'] ? response['result'].to_i : false
23
+ end
24
+
25
+ private
26
+
27
+ def with_root(attributes)
28
+ { :invoice => attributes }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module Fortnox
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ id: 1
2
+ tdate: '2012-01-04'
3
+ ddate: '2012-02-03'
4
+ edate: '2012-02-03'
5
+ ourref: 'Foo Bar'
6
+ yourref: 'Bar Foo'
7
+ roundoff: 1.0
8
+ freight: 0.0
9
+ totalvat: 50.0
10
+ total: 250.0
11
+ contact:
12
+ id: 1
13
+ name: 'Example AB'
14
+ address: 'Example street'
15
+ city: 'Example'
16
+ zip: '123 45'
17
+ pricelist: 'A'
18
+ invoicerows:
19
+ invoicerow:
20
+ descr: 'Sample product'
21
+ price: 100.0
22
+ amount: 2.0
23
+ vat: 25.0
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ module Fortnox
4
+ describe Customer do
5
+ before(:each) { API.establish_connection }
6
+
7
+ it "should create customer and return it's id" do
8
+ VCR.use_cassette('customer/create') do
9
+ customer_id = Customer.create(fixtures(:invoice)["contact"])
10
+ customer_id.should be_a(Integer)
11
+ end
12
+ end
13
+
14
+ it "should update customer given by id and return it's id" do
15
+ VCR.use_cassette('customer/update') do
16
+ customer_id = Customer.update(fixtures(:invoice)["contact"].merge(:name => 'Example Customer'))
17
+ customer_id.should be_a(Integer)
18
+ customer_id.should eq(1)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module Fortnox
4
+ describe Invoice do
5
+ before(:each) { API.establish_connection }
6
+
7
+ it "should raise error on invalid invoice creation" do
8
+ VCR.use_cassette('invoice/create_invalid') do
9
+ lambda {
10
+ Invoice.create(fixtures(:invoice).delete('tdate'))
11
+ }.should raise_error(Error)
12
+ end
13
+ end
14
+
15
+ it "should create invoice and return it's id" do
16
+ VCR.use_cassette('invoice/create') do
17
+ invoice_no = Invoice.create(fixtures(:invoice))
18
+ invoice_no.should be_a(Integer)
19
+ end
20
+ end
21
+
22
+ it "should update invoice given by id and return it's id" do
23
+ VCR.use_cassette('invoice/update') do
24
+ invoice_no = Invoice.update(fixtures(:invoice).merge(:ourref => 'Foo Foo'))
25
+ invoice_no.should be_a(Integer)
26
+ invoice_no.should eq(1)
27
+ end
28
+ end
29
+
30
+ it "should destroy invoice given by id and return it's id" do
31
+ VCR.use_cassette('invoice/destroy') do
32
+ invoice_no = Invoice.destroy(1)
33
+ invoice_no.should be_a(Integer)
34
+ invoice_no.should eq(1)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ require "fortnox"
2
+ require "yaml"
3
+ require "vcr"
4
+
5
+
6
+ def fixtures(fixture)
7
+ @@fixtures ||= load_fixtures
8
+ @@fixtures[fixture]
9
+ end
10
+
11
+ def load_fixtures
12
+ fixtures = {}
13
+
14
+ Dir['spec/fixtures/*.yml'].each do |file|
15
+ name = File.basename(file, File.extname(file)).to_sym
16
+ fixtures[name] = YAML::load(File.open(file).read)
17
+ end
18
+
19
+ fixtures
20
+ end
21
+
22
+ VCR.config do |c|
23
+ c.default_cassette_options = {:match_requests_on => [:method, :uri, :body]}
24
+ c.cassette_library_dir = 'spec/fixtures/cassettes'
25
+ c.stub_with :webmock
26
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module Fortnox
4
+ describe API do
5
+ let(:query_params) { {:token => 'foo', :db => 'bar'} }
6
+
7
+ before :each do
8
+ API.establish_connection({:token => 'foo', :database => 'bar'})
9
+ API.stub(:post)
10
+ end
11
+
12
+ it "can establish a connection" do
13
+ API.connection.should eq(query_params)
14
+ end
15
+
16
+ it "can make post request" do
17
+ attributes = {:foo => 'bar'}
18
+
19
+ API.should_receive(:post).with('/test.php', {
20
+ :query => query_params,
21
+ :body => {:xml => '<foo>bar</foo>'}
22
+ })
23
+
24
+ API.run(:post, 'test', attributes)
25
+ end
26
+
27
+ it "can make post request with query parameters" do
28
+ attributes = {:foo => 'bar', :query => {:id => 1}}
29
+
30
+ API.should_receive(:post).with('/test.php', {
31
+ :query => query_params.merge(attributes[:query]),
32
+ :body => {:xml => '<foo>bar</foo>'}
33
+ })
34
+
35
+ API.run(:post, 'test', attributes)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ require "spec_helper"
2
+
3
+ module Fortnox
4
+ describe Customer do
5
+ let(:attributes) { {:id => 1, :name => 'Example AB'} }
6
+
7
+ it "makes a post request and dismisses specified id" do
8
+ Customer.stub(:run) { { 'result' => { 'id' => '2' } } }
9
+
10
+ Customer.should_receive(:run).with(:post, :set_contact, { :contact => attributes.reject { |k, v| k == :id } })
11
+ customer_number = Customer.create(attributes)
12
+
13
+ customer_number.should_not eq(attributes[:id])
14
+ end
15
+
16
+ it "makes a post request and preserves specified id" do
17
+ Customer.stub(:run) { {'result' => {'id' => '1'}} }
18
+
19
+ Customer.should_receive(:run).with(:post, :set_contact, {:contact => attributes})
20
+ customer_number = Customer.update(attributes)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ module Fortnox
4
+ describe Invoice do
5
+ let(:attributes) { {:id => 1, :ourref => 'Foo Bar', :yourref => 'Bar Foo'} }
6
+
7
+ before :each do
8
+ Invoice.stub(:run) { {'result' => {'id' => '2'}} }
9
+ end
10
+
11
+ it "makes a post request and dismisses specified id" do
12
+ Invoice.should_receive(:run).with(:post, :set_invoice, {:invoice => attributes.reject { |k,v| k == :id }})
13
+ invoice_number = Invoice.create(attributes)
14
+ invoice_number.should_not eq(attributes[:id])
15
+ end
16
+
17
+ it "makes a post request and preserves specified id" do
18
+ Invoice.should_receive(:run).with(:post, :set_invoice, {:invoice => attributes})
19
+ Invoice.update(attributes)
20
+ end
21
+
22
+ it "makes a post request with query parameter id" do
23
+ Invoice.stub(:run) { {'result' => '2'} }
24
+ Invoice.should_receive(:run).with(:post, :set_invoice_cancel, {:query => {:id => 2}})
25
+ Invoice.destroy(2)
26
+ end
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fortnox
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jonas Arnklint
14
+ - "Kevin Sj\xC3\xB6berg"
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-03-20 00:00:00 +01:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: rspec
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: vcr
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: webmock
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ type: :development
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: httparty
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :runtime
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ name: gyoku
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :runtime
91
+ version_requirements: *id005
92
+ description: Handle invoices and customers through the Fortnox API
93
+ email:
94
+ - jonas@fkw.se
95
+ - kev.sjoberg@gmail.com
96
+ executables: []
97
+
98
+ extensions: []
99
+
100
+ extra_rdoc_files: []
101
+
102
+ files:
103
+ - .gitignore
104
+ - .rspec
105
+ - Gemfile
106
+ - README
107
+ - Rakefile
108
+ - fortnox.gemspec
109
+ - lib/fortnox.rb
110
+ - lib/fortnox/api.rb
111
+ - lib/fortnox/customer.rb
112
+ - lib/fortnox/errors.rb
113
+ - lib/fortnox/invoice.rb
114
+ - lib/fortnox/version.rb
115
+ - spec/fixtures/invoice.yml
116
+ - spec/integration/customer_spec.rb
117
+ - spec/integration/invoice_spec.rb
118
+ - spec/spec_helper.rb
119
+ - spec/unit/api_spec.rb
120
+ - spec/unit/customer_spec.rb
121
+ - spec/unit/invoice_spec.rb
122
+ has_rdoc: true
123
+ homepage: ""
124
+ licenses: []
125
+
126
+ post_install_message:
127
+ rdoc_options: []
128
+
129
+ require_paths:
130
+ - lib
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ hash: 3
146
+ segments:
147
+ - 0
148
+ version: "0"
149
+ requirements: []
150
+
151
+ rubyforge_project: fortnox
152
+ rubygems_version: 1.6.2
153
+ signing_key:
154
+ specification_version: 3
155
+ summary: Handle invoices and customers through the Fortnox API
156
+ test_files:
157
+ - spec/fixtures/invoice.yml
158
+ - spec/integration/customer_spec.rb
159
+ - spec/integration/invoice_spec.rb
160
+ - spec/spec_helper.rb
161
+ - spec/unit/api_spec.rb
162
+ - spec/unit/customer_spec.rb
163
+ - spec/unit/invoice_spec.rb