kashflow_api 0.0.1pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.markdown +35 -0
- data/Rakefile +1 -0
- data/kashflow_api.gemspec +26 -0
- data/lib/kashflow_api/api.rb +29 -0
- data/lib/kashflow_api/api_call.rb +102 -0
- data/lib/kashflow_api/client.rb +25 -0
- data/lib/kashflow_api/config.rb +14 -0
- data/lib/kashflow_api/models/customer.rb +85 -0
- data/lib/kashflow_api/models/customer_balance.rb +12 -0
- data/lib/kashflow_api/models/invoice.rb +47 -0
- data/lib/kashflow_api/models/line.rb +38 -0
- data/lib/kashflow_api/models/nominal_code.rb +12 -0
- data/lib/kashflow_api/models/quote.rb +14 -0
- data/lib/kashflow_api/models/receipt.rb +43 -0
- data/lib/kashflow_api/models/supplier.rb +62 -0
- data/lib/kashflow_api/soap_object.rb +40 -0
- data/lib/kashflow_api/version.rb +3 -0
- data/lib/kashflow_api.rb +44 -0
- data/spec/kashflow_api_customer_balance_spec.rb +20 -0
- data/spec/kashflow_api_customer_spec.rb +70 -0
- data/spec/kashflow_api_nominal_codes_spec.rb +15 -0
- data/spec/kashflow_api_quote_spec.rb +14 -0
- data/spec/kashflow_api_spec.rb +51 -0
- data/spec/kashflow_api_supplier_spec.rb +24 -0
- data/spec/spec_helper.rb +18 -0
- metadata +130 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# KashflowApi
|
2
|
+
|
3
|
+
KashflowApi provides an Active Record like interface to the Kashflow API.
|
4
|
+
|
5
|
+
# Usage
|
6
|
+
|
7
|
+
At the beginning of your program, or in an rails initializer call the configure block like so:
|
8
|
+
|
9
|
+
KashflowApi.configure do |c|
|
10
|
+
c.username = "Username"
|
11
|
+
c.password = "Password"
|
12
|
+
c.loggers = false
|
13
|
+
end
|
14
|
+
|
15
|
+
I recommend settings loggers to false so that you don't get all the soap exchanges echoed out.
|
16
|
+
|
17
|
+
You can now call methods on the models e.g.
|
18
|
+
|
19
|
+
KashflowApi::Customer.all
|
20
|
+
|
21
|
+
# Unimplemented Methods
|
22
|
+
|
23
|
+
Some of the methods in the Kashflow API have not been implemented in this gem (yet)
|
24
|
+
|
25
|
+
## Customers
|
26
|
+
|
27
|
+
* GetCustomersModifiedSince
|
28
|
+
* GetCustomerSources
|
29
|
+
* GetCustomerVATNumber
|
30
|
+
* SetCustomerVATNumber
|
31
|
+
* GetCustomerCurrency
|
32
|
+
* SetCustomerCurrency
|
33
|
+
* GetCustomerAdvancePayments
|
34
|
+
|
35
|
+
## Quotes
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "kashflow_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "kashflow_api"
|
7
|
+
s.version = KashflowApi::VERSION
|
8
|
+
s.authors = ["Adam \"Arcath\" Laycock"]
|
9
|
+
s.email = ["gems@arcath.net"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Provides an interface for the Kashflow API}
|
12
|
+
s.description = s.summary
|
13
|
+
|
14
|
+
s.rubyforge_project = "kashflow_api"
|
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
|
+
# Development Dependencies
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
|
24
|
+
# Runtime Dependencies
|
25
|
+
s.add_runtime_dependency "savon"
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Api
|
3
|
+
def initialize
|
4
|
+
unless KashflowApi.config.username && KashflowApi.config.password
|
5
|
+
raise "Username and Password required"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.methods
|
10
|
+
@methods ||= generate_method_list
|
11
|
+
end
|
12
|
+
|
13
|
+
# Main Handler
|
14
|
+
def method_missing(method, argument = nil)
|
15
|
+
methods = KashflowApi.api_methods
|
16
|
+
if methods.include?(method)
|
17
|
+
KashflowApi::ApiCall.new(method, argument).result
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.generate_method_list
|
26
|
+
KashflowApi.client.client.wsdl.soap_actions
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class ApiCall
|
3
|
+
attr_reader :result, :xml, :method
|
4
|
+
|
5
|
+
def initialize(method, argument)
|
6
|
+
set_method(method)
|
7
|
+
build_xml(argument)
|
8
|
+
raise xml if @raise
|
9
|
+
@result = make_call
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def xml_header
|
15
|
+
"<?xml version=\"1.0\" encoding=\"utf-8\"?>
|
16
|
+
<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">
|
17
|
+
<soap:Body>\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
def xml_footer
|
21
|
+
"</soap:Body>
|
22
|
+
</soap:Envelope>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_method(method)
|
26
|
+
words = method.to_s.split("_")
|
27
|
+
words.map { |word| word.capitalize! }
|
28
|
+
@action = words.first.downcase
|
29
|
+
@object = words[1].downcase
|
30
|
+
words[words.count - 1] = words.last.upcase if words.last == "Id"
|
31
|
+
@field = words.last
|
32
|
+
@field = "Code" if method == :get_customer || @field == "Balance" || method == :get_supplier
|
33
|
+
@method = words.join
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_xml(argument)
|
37
|
+
@xml = xml_header
|
38
|
+
@xml += "<#{@method} xmlns=\"KashFlow\">\n"
|
39
|
+
@xml += user_details
|
40
|
+
@xml += argument_xml(argument)
|
41
|
+
@xml += "</#{@method}>\n"
|
42
|
+
@xml += xml_footer
|
43
|
+
end
|
44
|
+
|
45
|
+
def user_details
|
46
|
+
"<UserName>#{KashflowApi.config.username}</UserName>
|
47
|
+
<Password>#{KashflowApi.config.password}</Password>\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
def make_call
|
51
|
+
KashflowApi.client.call(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
def argument_xml(argument)
|
55
|
+
out = ""
|
56
|
+
if argument
|
57
|
+
if @action == "get"
|
58
|
+
if @object == "customer"
|
59
|
+
out = "<Customer#{@field}>#{argument}</Customer#{@field}>"
|
60
|
+
elsif @object == "customers"
|
61
|
+
out = "<#{@field}>#{argument}</#{@field}>"
|
62
|
+
elsif @object == "quote"
|
63
|
+
out = "<Quote#{@field}>#{argument}</Quote#{@field}>"
|
64
|
+
elsif @object == "supplier"
|
65
|
+
out = "<Supplier#{@field}>#{argument}</Supplier#{@field}>"
|
66
|
+
elsif @object == "receipt"
|
67
|
+
out = "<ReceiptNumber>#{argument}</ReceiptNumber>"
|
68
|
+
elsif @object == "invoice"
|
69
|
+
out = "<InvoiceNumber>#{argument}</InvoiceNumber>"
|
70
|
+
end
|
71
|
+
elsif @action == "update" || @action == "insert"
|
72
|
+
if @object == "customer"
|
73
|
+
out = "<custr>#{argument.to_xml}</custr>"
|
74
|
+
elsif @object == "supplier"
|
75
|
+
if @action == "insert"
|
76
|
+
out = "<supl>#{argument.to_xml}</supl>"
|
77
|
+
else
|
78
|
+
out = "<sup>#{argument.to_xml}</sup>"
|
79
|
+
end
|
80
|
+
elsif @object == "receipt"
|
81
|
+
if @field == "Line"
|
82
|
+
out = "<ReceiptID>#{argument.receiptid}</ReceiptID><InvLine>#{argument.to_xml}</InvLine>"
|
83
|
+
else
|
84
|
+
out = "<Inv>#{argument.to_xml}</Inv>"
|
85
|
+
end
|
86
|
+
elsif @object == "invoice"
|
87
|
+
if @field == "Line"
|
88
|
+
out = "<InvoiceID>#{argument.invoiceid}</InvoiceID><InvLine>#{argument.to_xml}</InvLine>"
|
89
|
+
else
|
90
|
+
out = "<Inv>#{argument.to_xml}</Inv>"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
elsif @action == "delete"
|
94
|
+
if @object == "customer"
|
95
|
+
out = "<CustomerID>#{argument}</CustomerID>"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
out
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Client
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@url = "https://securedwebapp.com/api/service.asmx?WSDL"
|
6
|
+
|
7
|
+
@client = Savon::Client.new @url
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(api_call)
|
11
|
+
result = @client.request("KashFlow/#{api_call.method}") do |soap|
|
12
|
+
soap.xml = api_call.xml
|
13
|
+
end
|
14
|
+
raise "Incorrect username or password" if result.to_hash.first.last[:status_detail] == "Incorrect username or password"
|
15
|
+
raise "Your IP Address is not in the access list!" if result.to_hash.first.last[:status_detail] =~ /The IP address of .*? is not in the access list/
|
16
|
+
#raise api_call.xml if result.to_hash.first.last[:status] == "NO"
|
17
|
+
raise "Kashflow Error: #{result.to_hash.first.last[:status_detail]}" if result.to_hash.first.last[:status] == "NO"
|
18
|
+
return result
|
19
|
+
end
|
20
|
+
|
21
|
+
def client
|
22
|
+
@client
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Customer < KashflowApi::SoapObject
|
3
|
+
def self.find(search)
|
4
|
+
self.find_by_customer_code(search)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.find_by_customer_code(search)
|
8
|
+
result = KashflowApi.api.get_customer(search)
|
9
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomerResponse"]["GetCustomerResult"])
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.find_by_customer_id(search)
|
13
|
+
result = KashflowApi.api.get_customer_by_id(search)
|
14
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomerByIDResponse"]["GetCustomerByIDResult"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_by_customer_email(search)
|
18
|
+
result = KashflowApi.api.get_customer_by_email(search)
|
19
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomerByEmailResponse"]["GetCustomerByEmailResult"])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.find_by_postcode(search)
|
23
|
+
result = KashflowApi.api.get_customers_by_postcode(search)
|
24
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomersByPostcodeResponse"]["GetCustomersByPostcode"])
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.all
|
28
|
+
result = KashflowApi.api.get_customers
|
29
|
+
customers = []
|
30
|
+
result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomersResponse"]["GetCustomersResult"]["Customer"].each do |customer|
|
31
|
+
customers.push self.build_from_soap customer
|
32
|
+
end
|
33
|
+
customers
|
34
|
+
end
|
35
|
+
|
36
|
+
def save
|
37
|
+
if @hash["CustomerID"] == "0"
|
38
|
+
insert_customer
|
39
|
+
else
|
40
|
+
update_customer
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def destroy
|
45
|
+
KashflowApi.api.delete_customer(self.customerid)
|
46
|
+
end
|
47
|
+
|
48
|
+
def balance
|
49
|
+
KashflowApi::CustomerBalance.new(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_xml
|
53
|
+
xml = []
|
54
|
+
id_line = ""
|
55
|
+
@hash.keys.each do |key|
|
56
|
+
if key == "CustomerID"
|
57
|
+
id_line = "<#{key}>#{@hash[key]}</#{key}>" unless @hash[key] == "0"
|
58
|
+
else
|
59
|
+
xml.push("<#{key}>#{@hash[key]}</#{key}>")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
[id_line, xml.join].join
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def blank_object_hash
|
68
|
+
{"Code" => "", "Name" => "", "Contact" => "", "Telephone" => "", "Mobile" => "", "Fax" => "", "Email" => "", "Address1" => "", "Address2" => "",
|
69
|
+
"Address3" => "", "Address4" => "", "Postcode" => "", "Website" => "", "Notes" => "", "ExtraText1" => "", "ExtraText2" => "",
|
70
|
+
"ExtraText3" => "", "ExtraText4" => "", "ExtraText5" => "", "ExtraText6" => "", "ExtraText7" => "", "ExtraText8" => "", "ExtraText9" => "",
|
71
|
+
"ExtraText10" => "", "ExtraText11" => "", "ExtraText12" => "", "ExtraText13" => "", "ExtraText14" => "", "ExtraText15" => "",
|
72
|
+
"ExtraText16" => "", "ExtraText17" => "", "ExtraText18" => "", "ExtraText19" => "", "ExtraText20" => "", "ContactTitle" => "",
|
73
|
+
"ContactFirstName" => "", "ContactLastName" => "", "CustHasDeliveryAddress" => "0", "DeliveryAddress1" => "",
|
74
|
+
"DeliveryAddress2" => "", "DeliveryAddress3" => "", "DeliveryAddress4" => "", "DeliveryPostcode" => ""}.merge(KashflowApi::Customer.find("").hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
def update_customer
|
78
|
+
KashflowApi.api.update_customer(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
def insert_customer
|
82
|
+
KashflowApi.api.insert_customer(self)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class CustomerBalance
|
3
|
+
attr_reader :customer, :value, :balance
|
4
|
+
|
5
|
+
def initialize(customer)
|
6
|
+
result = KashflowApi.api.get_customer_balance(customer.code)
|
7
|
+
@customer = customer
|
8
|
+
@value = result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomerBalanceResponse"]["GetCustomerBalanceResult"]["Value"].to_f
|
9
|
+
@balance = result.basic_hash["soap:Envelope"]["soap:Body"]["GetCustomerBalanceResponse"]["GetCustomerBalanceResult"]["Balance"].to_f
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Invoice < KashflowApi::SoapObject
|
3
|
+
def self.find(search)
|
4
|
+
result = KashflowApi.api.get_invoice(search)
|
5
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetInvoiceResponse"]["GetInvoiceResult"])
|
6
|
+
end
|
7
|
+
|
8
|
+
def customer
|
9
|
+
KashflowApi::Customer.find_by_customer_id(self.customerid)
|
10
|
+
end
|
11
|
+
|
12
|
+
def save
|
13
|
+
if @hash["InvoiceDBID"] == "0"
|
14
|
+
insert_invoice
|
15
|
+
else
|
16
|
+
update_invoice
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_xml
|
21
|
+
xml = []
|
22
|
+
id_line = ""
|
23
|
+
@hash.keys.each do |key|
|
24
|
+
if key == "InvoiceDBID"
|
25
|
+
id_line = "<#{key}>#{@hash[key]}</#{key}>" unless @hash[key] == "0"
|
26
|
+
else
|
27
|
+
xml.push("<#{key}>#{@hash[key]}</#{key}>")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
[id_line, xml.join].join
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def blank_object_hash
|
36
|
+
{ "InvoiceNumber" => "", "InvoiceDate" => "", "DueDate" => "", "CustomerID" => "", "CustomerReference" => "", "InvoiceDBID" => "0" }
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_invoice
|
40
|
+
KashflowApi.api.update_invoice(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
def insert_invoice
|
44
|
+
KashflowApi.api.insert_invoice(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Line < KashflowApi::SoapObject
|
3
|
+
def save
|
4
|
+
if @hash["ReceiptID"] != ""
|
5
|
+
insert_receipt_line
|
6
|
+
elsif @hash["InvoiceID"] != ""
|
7
|
+
insert_invoice_line
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_xml
|
12
|
+
xml = []
|
13
|
+
id_line = ""
|
14
|
+
@hash.keys.each do |key|
|
15
|
+
if key == "LineID"
|
16
|
+
id_line = "<#{key}>#{@hash[key]}</#{key}>" unless @hash[key] == "0"
|
17
|
+
elsif key != "ReceiptID" && key != "InvoiceID" && @hash[key] != ""
|
18
|
+
xml.push("<#{key}>#{@hash[key]}</#{key}>")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
[id_line, xml.join].join
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def blank_object_hash
|
27
|
+
{"Quantity" => "", "Description" => "", "ChargeType" => "", "VatAmount" => "", "VatRate" => "", "Rate" => "", "ReceiptID" => "", "InvoiceID" => "" }
|
28
|
+
end
|
29
|
+
|
30
|
+
def insert_receipt_line
|
31
|
+
KashflowApi.api.insert_receipt_line(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
def insert_invoice_line
|
35
|
+
KashflowApi.api.insert_invoice_line(self)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class NominalCode < KashflowApi::SoapObject
|
3
|
+
def self.all
|
4
|
+
result = KashflowApi.api.get_nominal_codes
|
5
|
+
codes = []
|
6
|
+
result.basic_hash["soap:Envelope"]["soap:Body"]["GetNominalCodesResponse"]["GetNominalCodesResult"]["NominalCode"].each do |code|
|
7
|
+
codes.push(self.build_from_soap(code))
|
8
|
+
end
|
9
|
+
codes
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Quote < KashflowApi::Invoice
|
3
|
+
def self.find_by_id(search)
|
4
|
+
result = KashflowApi.api.get_quote_by_id(search)
|
5
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetQuoteByIDResponse"]["GetQuoteByIDResult"])
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def blank_object_hash
|
11
|
+
{}.merge(KashflowApi::Quote.find_by_id("0").hash)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Receipt < KashflowApi::SoapObject
|
3
|
+
def self.find(search)
|
4
|
+
result = KashflowApi.api.get_receipt(search)
|
5
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetReceiptResponse"]["GetReceiptResult"])
|
6
|
+
end
|
7
|
+
|
8
|
+
def save
|
9
|
+
if @hash["InvoiceDBID"] == "0"
|
10
|
+
insert_receipt
|
11
|
+
else
|
12
|
+
update_receipt
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_xml
|
17
|
+
xml = []
|
18
|
+
id_line = ""
|
19
|
+
@hash.keys.each do |key|
|
20
|
+
if key == "InvoiceDBID"
|
21
|
+
id_line = "<#{key}>#{@hash[key]}</#{key}>" unless @hash[key] == "0"
|
22
|
+
else
|
23
|
+
xml.push("<#{key}>#{@hash[key]}</#{key}>")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
[id_line, xml.join].join
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def blank_object_hash
|
32
|
+
{ "InvoiceNumber" => "", "InvoiceDate" => "", "DueDate" => "", "CustomerID" => "", "CustomerReference" => "", "InvoiceDBID" => "0" }
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_receipt
|
36
|
+
KashflowApi.api.update_receipt(self)
|
37
|
+
end
|
38
|
+
|
39
|
+
def insert_receipt
|
40
|
+
KashflowApi.api.insert_receipt(self)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class Supplier < KashflowApi::SoapObject
|
3
|
+
def self.find(search)
|
4
|
+
self.find_by_supplier_code(search)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.find_by_supplier_code(search)
|
8
|
+
result = KashflowApi.api.get_supplier(search)
|
9
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetSupplierResponse"]["GetSupplierResult"])
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.find_by_supplier_id(search)
|
13
|
+
result = KashflowApi.api.get_supplier_by_id(search)
|
14
|
+
self.build_from_soap(result.basic_hash["soap:Envelope"]["soap:Body"]["GetSupplierByIDResponse"]["GetSupplierByIDResult"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.all
|
18
|
+
result = KashflowApi.api.get_suppliers
|
19
|
+
suppliers = []
|
20
|
+
result.basic_hash["soap:Envelope"]["soap:Body"]["GetSuppliersResponse"]["GetSuppliersResult"]["Supplier"].each do |supplier|
|
21
|
+
suppliers.push self.build_from_soap supplier
|
22
|
+
end
|
23
|
+
suppliers.sort { |x, y| x.name <=> y.name }
|
24
|
+
end
|
25
|
+
|
26
|
+
def save
|
27
|
+
if @hash["SupplierID"] == "0"
|
28
|
+
insert_supplier
|
29
|
+
else
|
30
|
+
update_supplier
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_xml
|
35
|
+
xml = []
|
36
|
+
id_line = ""
|
37
|
+
@hash.keys.each do |key|
|
38
|
+
if key == "SupplierID"
|
39
|
+
id_line = "<#{key}>#{@hash[key]}</#{key}>" unless @hash[key] == "0"
|
40
|
+
else
|
41
|
+
xml.push("<#{key}>#{@hash[key]}</#{key}>")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
[id_line, xml.join].join
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def blank_object_hash
|
50
|
+
{"Code" => "", "Name" => "", "Contact" => "", "Telephone" => "", "Mobile" => "", "Fax" => "", "Email" => "", "Address1" => "", "Address2" => "",
|
51
|
+
"Address3" => "", "Address4" => "", "Postcode" => "", "Website" => "", "VATNumber" => "", "Notes" => ""}.merge(KashflowApi::Supplier.find("").hash)
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_supplier
|
55
|
+
KashflowApi.api.update_supplier(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
def insert_supplier
|
59
|
+
KashflowApi.api.insert_supplier(self)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module KashflowApi
|
2
|
+
class SoapObject
|
3
|
+
attr_accessor :hash
|
4
|
+
|
5
|
+
def initialize(hash = nil)
|
6
|
+
if hash
|
7
|
+
@hash = hash
|
8
|
+
build_field_hash
|
9
|
+
else
|
10
|
+
@hash = blank_object_hash
|
11
|
+
build_field_hash
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(method, set = nil)
|
16
|
+
if @fields.keys.include? method
|
17
|
+
@hash[@fields[method]]
|
18
|
+
elsif method.to_s.scan(/.$/).join == "="
|
19
|
+
if @fields.keys.include? method.to_s.gsub(/\=/,'').to_sym
|
20
|
+
@hash[@fields[method.to_s.gsub(/\=/,'').to_sym]] = set
|
21
|
+
end
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.build_from_soap(hash)
|
28
|
+
self.new(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def build_field_hash
|
34
|
+
@fields = {}
|
35
|
+
@hash.keys.each do |key|
|
36
|
+
@fields[key.downcase.to_sym] = key
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/kashflow_api.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Gems
|
2
|
+
require "savon"
|
3
|
+
# Kashflow Main Clases
|
4
|
+
require "kashflow_api/soap_object" # Soap Object Class
|
5
|
+
require "kashflow_api/config" # Config Class
|
6
|
+
# Kashflow Api Modules & Classes
|
7
|
+
require "kashflow_api/api" # Api Class
|
8
|
+
require "kashflow_api/api_call" # ApiCall Class
|
9
|
+
require "kashflow_api/client" # Client Class
|
10
|
+
# Models
|
11
|
+
require "kashflow_api/models/customer" # Customer Class
|
12
|
+
require "kashflow_api/models/customer_balance" # Customer Balance
|
13
|
+
require "kashflow_api/models/invoice" # Invoice Class
|
14
|
+
require "kashflow_api/models/line" # Invoice Line
|
15
|
+
require "kashflow_api/models/nominal_code" # Nominal Code
|
16
|
+
require "kashflow_api/models/quote" # Quote Class
|
17
|
+
require "kashflow_api/models/receipt" # Receipt Class
|
18
|
+
require "kashflow_api/models/supplier" # Supplier
|
19
|
+
# Version
|
20
|
+
require "kashflow_api/version"
|
21
|
+
|
22
|
+
module KashflowApi
|
23
|
+
def self.configure
|
24
|
+
@config = Config.new
|
25
|
+
yield @config
|
26
|
+
@api = Api.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.config
|
30
|
+
@config
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.api
|
34
|
+
@api
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.api_methods
|
38
|
+
@api_methods ||= Api.methods
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.client
|
42
|
+
@client ||= Client.new(@config)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi::CustomerBalance do
|
6
|
+
before :each do
|
7
|
+
default_config
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should create a new balance object" do
|
11
|
+
customer = KashflowApi::Customer.find(test_data("customer_code"))
|
12
|
+
customer.balance.should be_a KashflowApi::CustomerBalance
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have a balance and a value" do
|
16
|
+
customer = KashflowApi::Customer.find(test_data("customer_code"))
|
17
|
+
customer.balance.value.should be_a Float
|
18
|
+
customer.balance.balance.should be_a Float
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi::Customer do
|
6
|
+
before :each do
|
7
|
+
default_config
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should find a customer" do
|
11
|
+
KashflowApi::Customer.find_by_customer_code(test_data("customer_code")).should be_a KashflowApi::Customer
|
12
|
+
KashflowApi::Customer.find(test_data("customer_code")).should be_a KashflowApi::Customer
|
13
|
+
end
|
14
|
+
|
15
|
+
it "a found customer should have a name" do
|
16
|
+
KashflowApi::Customer.find_by_customer_code(test_data("customer_code")).name.should eq(test_data("customer_name"))
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return an array for .all" do
|
20
|
+
all = KashflowApi::Customer.all
|
21
|
+
all.should be_a Array
|
22
|
+
all.first.should be_a KashflowApi::Customer
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should find a customer by kashflowid" do
|
26
|
+
KashflowApi::Customer.find_by_customer_id(test_data("customer_id")).should be_a KashflowApi::Customer
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should find a customer by email" do
|
30
|
+
KashflowApi::Customer.find_by_customer_email(test_data("customer_email")).should be_a KashflowApi::Customer
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should find a customer by postcode" do
|
34
|
+
KashflowApi::Customer.find_by_postcode(test_data("customer_postcode")).should be_a KashflowApi::Customer
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should create a blank customer for a new" do
|
38
|
+
customer = KashflowApi::Customer.new
|
39
|
+
customer.should be_a KashflowApi::Customer
|
40
|
+
customer.name.should eq("")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set values" do
|
44
|
+
customer = KashflowApi::Customer.find(test_data("customer_code"))
|
45
|
+
check = customer.name
|
46
|
+
customer.name = "testing"
|
47
|
+
customer.name.should_not eq check
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should update a customer" do
|
51
|
+
prechange = KashflowApi::Customer.find(test_data("customer_code"))
|
52
|
+
change_back_to = prechange.address2
|
53
|
+
prechange.address2 = "rspec_tests"
|
54
|
+
prechange.save
|
55
|
+
postchange = KashflowApi::Customer.find(test_data("customer_code"))
|
56
|
+
postchange.address2.should eq "rspec_tests"
|
57
|
+
postchange.address2 = change_back_to
|
58
|
+
postchange.save
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should create a new customer and then destroy it" do
|
62
|
+
customer = KashflowApi::Customer.new
|
63
|
+
customer.name = "Rspec Test School"
|
64
|
+
customer.code = "RSPEC"
|
65
|
+
customer.save
|
66
|
+
search = KashflowApi::Customer.find("RSPEC")
|
67
|
+
search.name.should eq "Rspec Test School"
|
68
|
+
search.destroy
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi::CustomerBalance do
|
6
|
+
before :each do
|
7
|
+
default_config
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should find all nominal codes" do
|
11
|
+
all = KashflowApi::NominalCode.all
|
12
|
+
all.should be_a Array
|
13
|
+
all.first.should be_a KashflowApi::NominalCode
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi::Quote do
|
6
|
+
before :each do
|
7
|
+
default_config
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should create a blank quote for new" do
|
11
|
+
quote = KashflowApi::Quote.new
|
12
|
+
quote.should be_a KashflowApi::Quote
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi do
|
6
|
+
it "should raise an exception if username and password are not present" do
|
7
|
+
lambda{
|
8
|
+
KashflowApi.configure do |c|
|
9
|
+
end
|
10
|
+
}.should raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should take a username and password" do
|
14
|
+
KashflowApi.configure do |c|
|
15
|
+
c.username = "Test"
|
16
|
+
c.password = "test"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return an array of symbols for .api_methods" do
|
21
|
+
KashflowApi.configure do |c|
|
22
|
+
c.username = "Test"
|
23
|
+
c.password = "test"
|
24
|
+
end
|
25
|
+
|
26
|
+
KashflowApi.api_methods.should be_a Array
|
27
|
+
KashflowApi.api_methods.first.should be_a Symbol
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should raise an exception if username and password are wrong" do
|
31
|
+
lambda{
|
32
|
+
KashflowApi.configure do |c|
|
33
|
+
c.username = "Test"
|
34
|
+
c.password = "test"
|
35
|
+
c.loggers = false
|
36
|
+
end
|
37
|
+
|
38
|
+
KashflowApi::Customer.all
|
39
|
+
}.should raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should disable the loggers if requested" do
|
43
|
+
KashflowApi.configure do |c|
|
44
|
+
c.username = "Test"
|
45
|
+
c.password = "test"
|
46
|
+
c.loggers = false
|
47
|
+
end
|
48
|
+
|
49
|
+
KashflowApi.api_methods
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec/spec_helper'
|
2
|
+
# Require the gem
|
3
|
+
require 'lib/kashflow_api'
|
4
|
+
|
5
|
+
describe KashflowApi::Supplier do
|
6
|
+
before :each do
|
7
|
+
default_config
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should find a supplier" do
|
11
|
+
KashflowApi::Supplier.find(test_data("supplier_code")).should be_a KashflowApi::Supplier
|
12
|
+
KashflowApi::Supplier.find_by_supplier_code(test_data("supplier_code")).should be_a KashflowApi::Supplier
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return an array for .all" do
|
16
|
+
all = KashflowApi::Supplier.all
|
17
|
+
all.should be_a Array
|
18
|
+
all.first.should be_a KashflowApi::Supplier
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should find a supplier by kashflowid" do
|
22
|
+
KashflowApi::Supplier.find_by_supplier_id(test_data("supplier_id")).should be_a KashflowApi::Supplier
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
|
4
|
+
def default_config
|
5
|
+
KashflowApi.configure do |c|
|
6
|
+
c.username = yaml["username"]
|
7
|
+
c.password = yaml["password"]
|
8
|
+
c.loggers = false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def yaml
|
13
|
+
@yaml ||= YAML::load(File.open('spec/test_data.yml'))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_data(field)
|
17
|
+
@yaml[field]
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kashflow_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 961915968
|
5
|
+
prerelease: 5
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
- pre
|
11
|
+
version: 0.0.1pre
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- Adam "Arcath" Laycock
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2012-02-17 00:00:00 +00: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: savon
|
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: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
description: Provides an interface for the Kashflow API
|
51
|
+
email:
|
52
|
+
- gems@arcath.net
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- .gitignore
|
61
|
+
- Gemfile
|
62
|
+
- README.markdown
|
63
|
+
- Rakefile
|
64
|
+
- kashflow_api.gemspec
|
65
|
+
- lib/kashflow_api.rb
|
66
|
+
- lib/kashflow_api/api.rb
|
67
|
+
- lib/kashflow_api/api_call.rb
|
68
|
+
- lib/kashflow_api/client.rb
|
69
|
+
- lib/kashflow_api/config.rb
|
70
|
+
- lib/kashflow_api/models/customer.rb
|
71
|
+
- lib/kashflow_api/models/customer_balance.rb
|
72
|
+
- lib/kashflow_api/models/invoice.rb
|
73
|
+
- lib/kashflow_api/models/line.rb
|
74
|
+
- lib/kashflow_api/models/nominal_code.rb
|
75
|
+
- lib/kashflow_api/models/quote.rb
|
76
|
+
- lib/kashflow_api/models/receipt.rb
|
77
|
+
- lib/kashflow_api/models/supplier.rb
|
78
|
+
- lib/kashflow_api/soap_object.rb
|
79
|
+
- lib/kashflow_api/version.rb
|
80
|
+
- spec/kashflow_api_customer_balance_spec.rb
|
81
|
+
- spec/kashflow_api_customer_spec.rb
|
82
|
+
- spec/kashflow_api_nominal_codes_spec.rb
|
83
|
+
- spec/kashflow_api_quote_spec.rb
|
84
|
+
- spec/kashflow_api_spec.rb
|
85
|
+
- spec/kashflow_api_supplier_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: ""
|
89
|
+
licenses: []
|
90
|
+
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 3
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 25
|
111
|
+
segments:
|
112
|
+
- 1
|
113
|
+
- 3
|
114
|
+
- 1
|
115
|
+
version: 1.3.1
|
116
|
+
requirements: []
|
117
|
+
|
118
|
+
rubyforge_project: kashflow_api
|
119
|
+
rubygems_version: 1.4.2
|
120
|
+
signing_key:
|
121
|
+
specification_version: 3
|
122
|
+
summary: Provides an interface for the Kashflow API
|
123
|
+
test_files:
|
124
|
+
- spec/kashflow_api_customer_balance_spec.rb
|
125
|
+
- spec/kashflow_api_customer_spec.rb
|
126
|
+
- spec/kashflow_api_nominal_codes_spec.rb
|
127
|
+
- spec/kashflow_api_quote_spec.rb
|
128
|
+
- spec/kashflow_api_spec.rb
|
129
|
+
- spec/kashflow_api_supplier_spec.rb
|
130
|
+
- spec/spec_helper.rb
|