kashflow_api 0.0.1pre
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 +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
|