billysbilling-rails 1.1.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.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Guardfile +19 -0
- data/HISTORY.md +5 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/Rakefile +7 -0
- data/TODO.md +4 -0
- data/billysbilling-rails.gemspec +28 -0
- data/lib/.DS_Store +0 -0
- data/lib/billys_billing/.DS_Store +0 -0
- data/lib/billys_billing/account.rb +7 -0
- data/lib/billys_billing/association.rb +50 -0
- data/lib/billys_billing/attachment.rb +9 -0
- data/lib/billys_billing/base.rb +47 -0
- data/lib/billys_billing/client.rb +138 -0
- data/lib/billys_billing/config.rb +73 -0
- data/lib/billys_billing/contact.rb +11 -0
- data/lib/billys_billing/daybook_transaction.rb +10 -0
- data/lib/billys_billing/invoice.rb +16 -0
- data/lib/billys_billing/line.rb +11 -0
- data/lib/billys_billing/organization.rb +8 -0
- data/lib/billys_billing/payment.rb +12 -0
- data/lib/billys_billing/person.rb +6 -0
- data/lib/billys_billing/product.rb +10 -0
- data/lib/billys_billing/request.rb +50 -0
- data/lib/billys_billing/vat_model.rb +8 -0
- data/lib/billys_billing/version.rb +16 -0
- data/lib/billys_billing.rb +62 -0
- data/lib/billysbilling-rails.rb +1 -0
- data/lib/billysbilling.rb +1 -0
- data/lib/hash.rb +32 -0
- data/spec/billys_billing/base_spec.rb +8 -0
- data/spec/billys_billing/invoice_spec.rb +35 -0
- data/spec/billys_billing/request_spec.rb +10 -0
- data/spec/billys_billing/test_spec.rb +28 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/invoice_macros.rb +5 -0
- metadata +234 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
# Capybara request specs
|
17
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
18
|
+
end
|
19
|
+
|
data/HISTORY.md
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Pylonweb I/S, Denmark
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# billysbilling-rails
|
2
|
+
|
3
|
+
A Ruby wrapper for the [Billys Billing API](https://dev.billysbilling.dk/api). Se also the homepage of [Billys Billing ](https://billysbilling.dk/)
|
4
|
+
|
5
|
+
READ BILLYS BILLING API TERMS BEFORE USE: https://dev.billysbilling.dk/api-terms
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'billysbilling-rails'
|
12
|
+
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install billysbilling-rails
|
17
|
+
|
18
|
+
## Configuration
|
19
|
+
|
20
|
+
Simply supply your Billys Billing API key in an initializer
|
21
|
+
|
22
|
+
BillysBilling.configure do |config|
|
23
|
+
config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
24
|
+
end
|
25
|
+
|
26
|
+
Now you can fetch data from Billys Billing by querying the BillysBilling class directly
|
27
|
+
|
28
|
+
BillysBilling.index_invoices # Returns all invoices
|
29
|
+
|
30
|
+
BillysBilling.show_invoice({invoiceID}) # Returns the invoice with the specified id.
|
31
|
+
|
32
|
+
Or you can instantiate your own instance of the class with the API_KEY set automatically
|
33
|
+
|
34
|
+
client = BillysBilling.new
|
35
|
+
|
36
|
+
\- **OR** -
|
37
|
+
|
38
|
+
|
39
|
+
If you for some reason need multiple instances of the client and do not want to have a default API_KEY you can specify the key when instantiating:
|
40
|
+
|
41
|
+
client1 = BillysBilling.new(:api_key => "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
|
42
|
+
client2 = BillysBilling.new(:api_key => "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY")
|
43
|
+
|
44
|
+
## Usage Examples
|
45
|
+
|
46
|
+
client = BillysBilling.new(api_key: 'abcdefghijklmnopqrstuvxyz123456789')
|
47
|
+
|
48
|
+
product_params = {
|
49
|
+
"name" => "Book",
|
50
|
+
"description" => "Very exciting story.",
|
51
|
+
"accountId" => "1681536-NjAl5urzeTSK",
|
52
|
+
"vatModelId"=> "1681513-RKyYI1GPOdZJ",
|
53
|
+
"productType"=> "product",
|
54
|
+
"productNo"=> "B291",
|
55
|
+
"suppliersProductNo"=> "S9322",
|
56
|
+
"prices"=> [
|
57
|
+
{
|
58
|
+
"currencyId"=> "DKK",
|
59
|
+
"unitPrice"=> 299
|
60
|
+
}
|
61
|
+
]
|
62
|
+
}
|
63
|
+
|
64
|
+
product = client.create_product(product_params)
|
65
|
+
product.description
|
66
|
+
#=> "Very exciting story."
|
67
|
+
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
1. Fork it
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/TODO.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/billys_billing/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Johan Frølich"]
|
6
|
+
gem.email = ["johanfrolich@gmail.com"]
|
7
|
+
gem.description = "A API for the danish accounting program, Billys Billing"
|
8
|
+
gem.summary = "A API for the danish accounting program, Billys Billing"
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "billysbilling-rails"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = BillysBilling::Version.to_s
|
17
|
+
|
18
|
+
gem.add_development_dependency "rspec"
|
19
|
+
gem.add_development_dependency "guard-rspec"
|
20
|
+
gem.add_development_dependency "rb-fsevent"
|
21
|
+
gem.add_development_dependency "growl"
|
22
|
+
gem.add_development_dependency "webmock"
|
23
|
+
gem.add_development_dependency "vcr"
|
24
|
+
|
25
|
+
gem.add_dependency "activesupport"
|
26
|
+
gem.add_dependency "activerecord"
|
27
|
+
gem.add_dependency "httparty"
|
28
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
# Defines associations methods
|
3
|
+
module Association
|
4
|
+
|
5
|
+
# Specifie a has one association
|
6
|
+
def has_one(name, options={})
|
7
|
+
class_name = options[:class_name] || name
|
8
|
+
class_eval do
|
9
|
+
# Creating setter method
|
10
|
+
define_method("#{name}=") do |attributes|
|
11
|
+
class_object = "BillysBilling::#{class_name.to_s.classify}".constantize
|
12
|
+
if attributes.is_a?(class_object)
|
13
|
+
instance = attributes
|
14
|
+
else
|
15
|
+
instance = class_object.new(attributes)
|
16
|
+
end
|
17
|
+
instance_variable_set("@#{name}", instance)
|
18
|
+
end
|
19
|
+
# Creating getter method
|
20
|
+
define_method(name) do
|
21
|
+
instance_variable_get("@#{name}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specifie a has many association
|
27
|
+
def has_many(name, options={})
|
28
|
+
class_name = options[:class_name] || name
|
29
|
+
instances = []
|
30
|
+
class_eval do
|
31
|
+
define_method("#{name}=") do |list|
|
32
|
+
class_object = "BillysBilling::#{class_name.to_s.classify}".constantize
|
33
|
+
list.each do |attributes|
|
34
|
+
if attributes.is_a?(class_object)
|
35
|
+
instances << attributes
|
36
|
+
else
|
37
|
+
instances << class_object.new(attributes)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
instance_variable_set("@#{name}", instances)
|
41
|
+
end
|
42
|
+
|
43
|
+
define_method(name) do
|
44
|
+
instance_variable_get("@#{name}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "billys_billing/association"
|
2
|
+
|
3
|
+
module BillysBilling
|
4
|
+
class Base
|
5
|
+
extend BillysBilling::Association
|
6
|
+
|
7
|
+
attr_accessor :attrs
|
8
|
+
alias :to_hash :attrs
|
9
|
+
|
10
|
+
# Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
|
11
|
+
#
|
12
|
+
# @overload self.lazy_attr_reader(attr)
|
13
|
+
# @param attr [Symbol]
|
14
|
+
# @overload self.lazy_attr_reader(attrs)
|
15
|
+
# @param attrs [Array<Symbol>]
|
16
|
+
def self.lazy_attr_reader(*attrs)
|
17
|
+
attrs.each do |attribute|
|
18
|
+
class_eval do
|
19
|
+
define_method attribute do
|
20
|
+
@attrs[attribute.to_s]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Initializes a new Base object
|
27
|
+
#
|
28
|
+
# @param attrs [Hash]
|
29
|
+
# @return [Twitter::Base]
|
30
|
+
def initialize(attrs={})
|
31
|
+
attrs.delete_if{|k,v| v.nil?}.each do |key, value|
|
32
|
+
self.send("#{key}=".to_sym, value)
|
33
|
+
# instance_variable_set("@#{key}", value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Initializes a new Base object
|
38
|
+
#
|
39
|
+
# @param method [String, Symbol] Message to send to the object
|
40
|
+
def [](method)
|
41
|
+
self.__send__(method.to_sym)
|
42
|
+
rescue NoMethodError
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'billys_billing/config'
|
2
|
+
require 'billys_billing/request'
|
3
|
+
|
4
|
+
require 'billys_billing/account'
|
5
|
+
require 'billys_billing/contact'
|
6
|
+
require 'billys_billing/invoice'
|
7
|
+
require 'billys_billing/line'
|
8
|
+
# require 'billys_billing/'
|
9
|
+
|
10
|
+
module BillysBilling
|
11
|
+
# Wrapper for the BillysBilling REST API
|
12
|
+
|
13
|
+
class Client
|
14
|
+
include BillysBilling::Request
|
15
|
+
|
16
|
+
attr_accessor *Config::VALID_OPTIONS_KEYS
|
17
|
+
|
18
|
+
# Initializes a new API object
|
19
|
+
#
|
20
|
+
# @param attrs [Hash]
|
21
|
+
# @return [BillysBilling::Client]
|
22
|
+
def initialize(attrs={})
|
23
|
+
attrs = BillysBilling.options.merge(attrs)
|
24
|
+
Config::VALID_OPTIONS_KEYS.each do |key|
|
25
|
+
instance_variable_set("@#{key}".to_sym, attrs[key])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(method, *arguments, &block)
|
30
|
+
# the first argument is a Symbol, so you need to_s it if you want to pattern match
|
31
|
+
if method.to_s =~ /^(#{valid_actions.join("|")})_(#{valid_queries.join("s?|")})(!?)/ && respond_to?($1)
|
32
|
+
send("#{$1}#{$3}", *[$2.pluralize].concat(arguments), &block)
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def respond_to?(method, include_private=false)
|
39
|
+
if method.to_s =~ /^(#{valid_actions.join("|")})_(#{valid_queries.join("|")})/
|
40
|
+
true
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def show!(class_name, id, options={})
|
47
|
+
show(class_name, id, options.merge({return_error_message: true}))
|
48
|
+
end
|
49
|
+
alias_method :find!, :show!
|
50
|
+
alias_method :get!, :show!
|
51
|
+
|
52
|
+
def index!(class_name, params={}, options={})
|
53
|
+
index(class_name, params, options.merge({return_error_message: true}))
|
54
|
+
end
|
55
|
+
alias_method :list!, :index!
|
56
|
+
|
57
|
+
def create!(class_name, params, options={})
|
58
|
+
create(class_name, params, options.merge({return_error_message: true}))
|
59
|
+
end
|
60
|
+
alias_method :new!, :create!
|
61
|
+
alias_method :add!, :create!
|
62
|
+
|
63
|
+
def update!(class_name, id, params, options={})
|
64
|
+
update(class_name, id, params, options.merge({return_error_message: true}))
|
65
|
+
end
|
66
|
+
|
67
|
+
def destroy!(class_name, id, options={})
|
68
|
+
destroy(class_name, id, options.merge({return_error_message: true}))
|
69
|
+
end
|
70
|
+
alias_method :delete!, :destroy!
|
71
|
+
|
72
|
+
def show(class_name, id, options={})
|
73
|
+
response = get_request("/#{class_name}/#{id}", options)
|
74
|
+
if response.success?
|
75
|
+
get_class_instance(class_name, response)
|
76
|
+
else
|
77
|
+
options[:return_error_message] ? response["error"] : false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
alias_method :find, :show
|
81
|
+
alias_method :get, :show
|
82
|
+
|
83
|
+
def index(class_name, params={}, options={})
|
84
|
+
params = {q: params} if params.is_a?(String)
|
85
|
+
|
86
|
+
list = []
|
87
|
+
response = get_request("/#{class_name}", params, options)
|
88
|
+
if response.success?
|
89
|
+
response[class_name].each do |instance|
|
90
|
+
list << get_class_instance(class_name, instance)
|
91
|
+
end
|
92
|
+
return list
|
93
|
+
else
|
94
|
+
options[:return_error_message] ? response["error"] : false
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
alias_method :list, :index
|
99
|
+
|
100
|
+
def create(class_name, params, options={})
|
101
|
+
response = post_request("/#{class_name}", params, options)
|
102
|
+
if response.success?
|
103
|
+
show(class_name, response["id"], options)
|
104
|
+
else
|
105
|
+
options[:return_error_message] ? response["error"] : false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
alias_method :new, :create
|
109
|
+
alias_method :add, :create
|
110
|
+
|
111
|
+
def update(class_name, id, params, options={})
|
112
|
+
response = put_request("/#{class_name}/#{id}", params, options)
|
113
|
+
if response.success?
|
114
|
+
show(class_name, id, options)
|
115
|
+
else
|
116
|
+
options[:return_error_message] ? response["error"] : false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def destroy(class_name, id, options={})
|
121
|
+
item = show(class_name, id, options)
|
122
|
+
response = delete_request("/#{class_name}/#{id}", options)
|
123
|
+
if response.success?
|
124
|
+
return item
|
125
|
+
else
|
126
|
+
options[:return_error_message] ? response["error"] : false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
alias_method :delete, :destroy
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
def get_class_instance(class_name, params)
|
134
|
+
"BillysBilling::#{class_name.to_s.classify}".constantize.new(params)
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'billys_billing/version'
|
2
|
+
|
3
|
+
module BillysBilling
|
4
|
+
# Defines constants and methods related to configuration
|
5
|
+
module Config
|
6
|
+
|
7
|
+
VALID_QUERIES = [
|
8
|
+
"contact",
|
9
|
+
"invoice",
|
10
|
+
"organization",
|
11
|
+
"payment",
|
12
|
+
"product",
|
13
|
+
"vat_model",
|
14
|
+
"account"
|
15
|
+
]
|
16
|
+
|
17
|
+
VALID_ACTIONS = [
|
18
|
+
"show",
|
19
|
+
# "get",
|
20
|
+
"index",
|
21
|
+
"list",
|
22
|
+
"create",
|
23
|
+
"add",
|
24
|
+
"update",
|
25
|
+
"destroy",
|
26
|
+
"delete"
|
27
|
+
]
|
28
|
+
|
29
|
+
# The api key if none is set
|
30
|
+
DEFAULT_API_KEY = nil
|
31
|
+
|
32
|
+
# The endpoint that will be used to connect if none is set
|
33
|
+
DEFAULT_ENDPOINT = 'https://api.billysbilling.dk/v1'
|
34
|
+
|
35
|
+
|
36
|
+
# An array of valid keys in the options hash when configuring a {BillysBilling::Client}
|
37
|
+
VALID_OPTIONS_KEYS = [
|
38
|
+
:api_key,
|
39
|
+
:endpoint,
|
40
|
+
:valid_actions,
|
41
|
+
:valid_queries
|
42
|
+
]
|
43
|
+
|
44
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
45
|
+
|
46
|
+
# When this module is extended, set all configuration options to their default values
|
47
|
+
def self.extended(base)
|
48
|
+
base.reset
|
49
|
+
end
|
50
|
+
|
51
|
+
# Convenience method to allow configuration options to be set in a block
|
52
|
+
def configure
|
53
|
+
yield self
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
# Create a hash of options and their values
|
58
|
+
def options
|
59
|
+
options = {}
|
60
|
+
VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
|
61
|
+
options
|
62
|
+
end
|
63
|
+
|
64
|
+
# Reset all configuration options to defaults
|
65
|
+
def reset
|
66
|
+
self.api_key = DEFAULT_API_KEY
|
67
|
+
self.endpoint = DEFAULT_ENDPOINT
|
68
|
+
self.valid_actions = VALID_ACTIONS
|
69
|
+
self.valid_queries = VALID_QUERIES
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class Contact < BillysBilling::Base
|
3
|
+
attr_accessor :id, :contact_no, :created_time, :name,
|
4
|
+
:street, :zipcode, :city, :country_id, :state, :phone, :fax,
|
5
|
+
:currency, :vat_no, :ean, :locale_id, :url, :persons, :success,
|
6
|
+
:country, :locale
|
7
|
+
|
8
|
+
has_many :persons
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class DaybookTransaction < BillysBilling::Base
|
3
|
+
attr_accessor :id, :created_time, :entry_date, :api_type, :description, :extended_description, :transaction_running_no,
|
4
|
+
:postings, :url, :success
|
5
|
+
|
6
|
+
|
7
|
+
has_many :attachments
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class Invoice < BillysBilling::Base
|
3
|
+
attr_accessor :id, :type, :created_time, :approved_time, :invoice_no, :entry_date,
|
4
|
+
:due_date, :state, :amount, :vat, :exchange_rate, :balance, :is_paid,
|
5
|
+
:contact_message, :print_url, :url, :success,
|
6
|
+
:currency
|
7
|
+
|
8
|
+
has_one :contact
|
9
|
+
has_one :att_contact_person, :class_name => "contact"
|
10
|
+
|
11
|
+
has_many :lines
|
12
|
+
has_many :payments
|
13
|
+
has_many :attachments
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class Line < BillysBilling::Base
|
3
|
+
attr_accessor :id, :description, :quantity, :unit_price, :discount_text, :discount_mode, :discount_value, :amount, :vat,
|
4
|
+
:vat_model
|
5
|
+
|
6
|
+
# belongs_to :invoice
|
7
|
+
has_one :product
|
8
|
+
has_one :vat_model
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class Payment < BillysBilling::Base
|
3
|
+
attr_accessor :id, :type, :created_time, :paid_date, :amount, :currency_id, :invoice_currency, :exchange_rate, :url, :success,
|
4
|
+
:currency
|
5
|
+
|
6
|
+
has_one :contact
|
7
|
+
has_one :account
|
8
|
+
|
9
|
+
has_many :invoices
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "httparty"
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
module BillysBilling
|
5
|
+
# Defines HTTP request methods
|
6
|
+
module Request
|
7
|
+
|
8
|
+
# Perform an HTTP DELETE request
|
9
|
+
def delete_request(path, params={}, options={})
|
10
|
+
request(:delete, path, params, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Perform an HTTP GET request
|
14
|
+
def get_request(path, params={}, options={})
|
15
|
+
request(:get, path, params, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Perform an HTTP POST request
|
19
|
+
def post_request(path, params={}, options={})
|
20
|
+
request(:post, path, params, options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Perform an HTTP PUT request
|
24
|
+
def put_request(path, params={}, options={})
|
25
|
+
request(:put, path, params, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Perform an HTTP request
|
31
|
+
def request(method, path, params, options)
|
32
|
+
params = params.billyfy_keys!
|
33
|
+
auth = {username: api_key, password: ""}
|
34
|
+
case method.to_sym
|
35
|
+
when :get
|
36
|
+
response = HTTParty.get(endpoint + path, :query => params, :basic_auth => auth)
|
37
|
+
when :post
|
38
|
+
response = HTTParty.post(endpoint + path, :body => MultiJson.encode(params), :basic_auth => auth)
|
39
|
+
when :delete
|
40
|
+
response = HTTParty.delete(endpoint + path, :query => params, :basic_auth => auth)
|
41
|
+
when :put
|
42
|
+
response = HTTParty.put(endpoint + path, :body => MultiJson.encode(params), :basic_auth => auth)
|
43
|
+
else
|
44
|
+
end
|
45
|
+
|
46
|
+
options[:raw] ? response : response.parsed_response.rubyify_keys!
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module BillysBilling
|
2
|
+
class Version #:nodoc:
|
3
|
+
@major = 1
|
4
|
+
@minor = 1
|
5
|
+
@tiny = 0
|
6
|
+
@build = nil
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_reader :major, :minor, :tiny, :build
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
[@major, @minor, @tiny, @build].compact.join('.')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
autoload :Account,"billys_billing/account"
|
2
|
+
autoload :Contact, "billys_billing/contact"
|
3
|
+
autoload :Invoice, "billys_billing/invoice"
|
4
|
+
autoload :Organization, "billys_billing/organization"
|
5
|
+
autoload :Payment, "billys_billing/payment"
|
6
|
+
autoload :Product, "billys_billing/product"
|
7
|
+
autoload :Vat_model, "billys_billing/vat_model"
|
8
|
+
autoload :Line, "billys_billing/line"
|
9
|
+
|
10
|
+
|
11
|
+
require 'hash'
|
12
|
+
require "active_support/inflector"
|
13
|
+
|
14
|
+
require 'billys_billing/base'
|
15
|
+
|
16
|
+
require 'billys_billing/person'
|
17
|
+
require 'billys_billing/account'
|
18
|
+
require 'billys_billing/attachment'
|
19
|
+
require 'billys_billing/contact'
|
20
|
+
require 'billys_billing/daybook_transaction'
|
21
|
+
require 'billys_billing/vat_model'
|
22
|
+
require 'billys_billing/payment'
|
23
|
+
require 'billys_billing/product'
|
24
|
+
require 'billys_billing/line'
|
25
|
+
require 'billys_billing/invoice'
|
26
|
+
|
27
|
+
require 'billys_billing/organization'
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
require 'billys_billing/client'
|
34
|
+
require 'billys_billing/config'
|
35
|
+
|
36
|
+
|
37
|
+
module BillysBilling
|
38
|
+
extend Config
|
39
|
+
class << self
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
# Alias for BillysBilling::Client.new
|
44
|
+
#
|
45
|
+
# @return [BillysBilling::Client]
|
46
|
+
def new(options={})
|
47
|
+
BillysBilling::Client.new(options)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Delegate to BillysBilling::Client
|
51
|
+
def method_missing(method, *args, &block)
|
52
|
+
return super unless new.respond_to?(method)
|
53
|
+
new.send(method, *args, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def respond_to?(method, include_private=false)
|
57
|
+
new.respond_to?(method, include_private) || super(method, include_private)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require "billys_billing"
|
@@ -0,0 +1 @@
|
|
1
|
+
require "billys_billing"
|
data/lib/hash.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "active_support/inflector"
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
|
5
|
+
# Converts all of the keys to strings, optionally formatting key name
|
6
|
+
def rubyify_keys!
|
7
|
+
keys.each{|k|
|
8
|
+
v = delete(k)
|
9
|
+
new_key = k.to_s.underscore
|
10
|
+
self[new_key] = v
|
11
|
+
v.rubyify_keys! if v.is_a?(Hash)
|
12
|
+
v.each{|p| p.rubyify_keys! if p.is_a?(Hash)} if v.is_a?(Array)
|
13
|
+
}
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def billyfy_keys!
|
18
|
+
keys.each{|k|
|
19
|
+
v = delete(k)
|
20
|
+
new_key = k.to_s.camelize(:lower)
|
21
|
+
self[new_key] = v
|
22
|
+
v.rubyify_keys! if v.is_a?(Hash)
|
23
|
+
v.each{|p| p.billyfy_keys! if p.is_a?(Hash)} if v.is_a?(Array)
|
24
|
+
}
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def success?
|
29
|
+
self["success"]
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# require "spec_helper"
|
2
|
+
#
|
3
|
+
# describe BillysBilling::Invoice do
|
4
|
+
# describe "#list" do
|
5
|
+
# it "should be success" do
|
6
|
+
# response = BillysBilling::Invoice.list()
|
7
|
+
# response["success"].should be_true
|
8
|
+
# end
|
9
|
+
# it "should include an array named 'invoices'" do
|
10
|
+
# response = BillysBilling::Invoice.list()
|
11
|
+
# response["invoices"].should be_an_instance_of(Array)
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# describe "#list with specific contact" do
|
16
|
+
# it "should be success" do
|
17
|
+
# response = BillysBilling::Invoice.list('1172167-iYZ2zDSyM3ib')
|
18
|
+
# response["success"].should be_true
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# it "should include an array named 'invoices'" do
|
22
|
+
# response = BillysBilling::Invoice.list('1172167-iYZ2zDSyM3ib')
|
23
|
+
# response["invoices"].should be_an_instance_of(Array)
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# describe "#get" do
|
28
|
+
# it "should return with success" do
|
29
|
+
# if iid = get_invoice_id
|
30
|
+
# response = BillysBilling::Invoice.get(iid)
|
31
|
+
# response["success"].should be_true
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
# end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BillysBilling::Request do
|
4
|
+
it "must include httparty methods" do
|
5
|
+
BillysBilling::Request.should_include HTTParty
|
6
|
+
end
|
7
|
+
it "must have the base url set to the Billys Billing API endpoint" do
|
8
|
+
BillysBilling::Request.base_uri.should_equal 'https://api.billysbilling.dk/v1'
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BillysBilling::Invoice do
|
4
|
+
it "invoice#index" do
|
5
|
+
# puts BillysBilling.index_products
|
6
|
+
# puts BillysBilling.index_vat_models.first
|
7
|
+
# puts BillysBilling.index_accounts.first
|
8
|
+
|
9
|
+
params = {
|
10
|
+
"name" => "Book",
|
11
|
+
"description" => "Very exciting story.",
|
12
|
+
"accountId" => "1681817-d2rh5fGoC3yt",
|
13
|
+
"vatModelId"=> "1681794-R01nOyyaKE9o",
|
14
|
+
"productType"=> "product",
|
15
|
+
"productNo"=> "B291",
|
16
|
+
"suppliersProductNo"=> "S9322",
|
17
|
+
"prices"=> [
|
18
|
+
{
|
19
|
+
"currencyId"=> "DKK",
|
20
|
+
"unitPrice"=> 299
|
21
|
+
}
|
22
|
+
]
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
puts BillysBilling.create_products(params)
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'billys_billing'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
require 'vcr'
|
4
|
+
|
5
|
+
Dir["#{Dir.pwd}/spec/support/**/*.rb"].each {|file| require file }
|
6
|
+
RSpec.configure do |config|
|
7
|
+
|
8
|
+
config.include InvoiceMacros
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
config.before(:each) do
|
14
|
+
BillysBilling.configure do |config|
|
15
|
+
config.api_key = "JYRkRPBsukN6YmV6PbouDQg8VclmAFzc"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#VCR config
|
22
|
+
VCR.config do |c|
|
23
|
+
c.cassette_library_dir = 'spec/fixtures/dish_cassettes'
|
24
|
+
c.stub_with :webmock
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: billysbilling-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Johan Frølich
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: guard-rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rb-fsevent
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: growl
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: vcr
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: activesupport
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: activerecord
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: httparty
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :runtime
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: A API for the danish accounting program, Billys Billing
|
159
|
+
email:
|
160
|
+
- johanfrolich@gmail.com
|
161
|
+
executables: []
|
162
|
+
extensions: []
|
163
|
+
extra_rdoc_files: []
|
164
|
+
files:
|
165
|
+
- .gitignore
|
166
|
+
- .rspec
|
167
|
+
- Gemfile
|
168
|
+
- Guardfile
|
169
|
+
- HISTORY.md
|
170
|
+
- LICENSE
|
171
|
+
- README.md
|
172
|
+
- Rakefile
|
173
|
+
- TODO.md
|
174
|
+
- billysbilling-rails.gemspec
|
175
|
+
- lib/.DS_Store
|
176
|
+
- lib/billys_billing.rb
|
177
|
+
- lib/billys_billing/.DS_Store
|
178
|
+
- lib/billys_billing/account.rb
|
179
|
+
- lib/billys_billing/association.rb
|
180
|
+
- lib/billys_billing/attachment.rb
|
181
|
+
- lib/billys_billing/base.rb
|
182
|
+
- lib/billys_billing/client.rb
|
183
|
+
- lib/billys_billing/config.rb
|
184
|
+
- lib/billys_billing/contact.rb
|
185
|
+
- lib/billys_billing/daybook_transaction.rb
|
186
|
+
- lib/billys_billing/invoice.rb
|
187
|
+
- lib/billys_billing/line.rb
|
188
|
+
- lib/billys_billing/organization.rb
|
189
|
+
- lib/billys_billing/payment.rb
|
190
|
+
- lib/billys_billing/person.rb
|
191
|
+
- lib/billys_billing/product.rb
|
192
|
+
- lib/billys_billing/request.rb
|
193
|
+
- lib/billys_billing/vat_model.rb
|
194
|
+
- lib/billys_billing/version.rb
|
195
|
+
- lib/billysbilling-rails.rb
|
196
|
+
- lib/billysbilling.rb
|
197
|
+
- lib/hash.rb
|
198
|
+
- spec/billys_billing/base_spec.rb
|
199
|
+
- spec/billys_billing/invoice_spec.rb
|
200
|
+
- spec/billys_billing/request_spec.rb
|
201
|
+
- spec/billys_billing/test_spec.rb
|
202
|
+
- spec/spec_helper.rb
|
203
|
+
- spec/support/invoice_macros.rb
|
204
|
+
homepage: ''
|
205
|
+
licenses: []
|
206
|
+
post_install_message:
|
207
|
+
rdoc_options: []
|
208
|
+
require_paths:
|
209
|
+
- lib
|
210
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
211
|
+
none: false
|
212
|
+
requirements:
|
213
|
+
- - ! '>='
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
requirements: []
|
223
|
+
rubyforge_project:
|
224
|
+
rubygems_version: 1.8.24
|
225
|
+
signing_key:
|
226
|
+
specification_version: 3
|
227
|
+
summary: A API for the danish accounting program, Billys Billing
|
228
|
+
test_files:
|
229
|
+
- spec/billys_billing/base_spec.rb
|
230
|
+
- spec/billys_billing/invoice_spec.rb
|
231
|
+
- spec/billys_billing/request_spec.rb
|
232
|
+
- spec/billys_billing/test_spec.rb
|
233
|
+
- spec/spec_helper.rb
|
234
|
+
- spec/support/invoice_macros.rb
|