twinfieldrb 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/rspec.yml +33 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -0
- data/README.md +120 -0
- data/Rakefile +1 -0
- data/lib/twinfield/abstract_model.rb +7 -0
- data/lib/twinfield/api/base_api.rb +50 -0
- data/lib/twinfield/api/finder.rb +45 -0
- data/lib/twinfield/api/o_auth_session.rb +58 -0
- data/lib/twinfield/api/process.rb +44 -0
- data/lib/twinfield/api/session.rb +170 -0
- data/lib/twinfield/browse/transaction/cost_center.rb +145 -0
- data/lib/twinfield/browse/transaction/customer.rb +413 -0
- data/lib/twinfield/browse/transaction/general_ledger.rb +144 -0
- data/lib/twinfield/configuration.rb +49 -0
- data/lib/twinfield/create/cost_center.rb +39 -0
- data/lib/twinfield/create/creditor.rb +88 -0
- data/lib/twinfield/create/debtor.rb +88 -0
- data/lib/twinfield/create/error.rb +30 -0
- data/lib/twinfield/create/general_ledger.rb +39 -0
- data/lib/twinfield/create/transaction.rb +97 -0
- data/lib/twinfield/customer.rb +612 -0
- data/lib/twinfield/helpers/parsers.rb +23 -0
- data/lib/twinfield/helpers/transaction_match.rb +40 -0
- data/lib/twinfield/request/find.rb +149 -0
- data/lib/twinfield/request/list.rb +66 -0
- data/lib/twinfield/request/read.rb +111 -0
- data/lib/twinfield/sales_invoice.rb +409 -0
- data/lib/twinfield/transaction.rb +112 -0
- data/lib/twinfield/version.rb +5 -0
- data/lib/twinfield.rb +89 -0
- data/script/boot.rb +58 -0
- data/script/console +2 -0
- data/spec/fixtures/cluster/finder/ivt.xml +1 -0
- data/spec/fixtures/cluster/processxml/columns/sales_transactions.xml +312 -0
- data/spec/fixtures/cluster/processxml/customer/create_success.xml +100 -0
- data/spec/fixtures/cluster/processxml/customer/read_success.xml +93 -0
- data/spec/fixtures/cluster/processxml/customer/update_success.xml +1 -0
- data/spec/fixtures/cluster/processxml/invoice/create_error.xml +8 -0
- data/spec/fixtures/cluster/processxml/invoice/create_final_error.xml +67 -0
- data/spec/fixtures/cluster/processxml/invoice/create_success.xml +64 -0
- data/spec/fixtures/cluster/processxml/invoice/read_not_found.xml +1 -0
- data/spec/fixtures/cluster/processxml/invoice/read_success.xml +106 -0
- data/spec/fixtures/cluster/processxml/read/deb.xml +12 -0
- data/spec/fixtures/cluster/processxml/response.xml +8 -0
- data/spec/fixtures/login/session/wsdl.xml +210 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/stubs/finder_stubs.rb +19 -0
- data/spec/stubs/processxml_stubs.rb +41 -0
- data/spec/stubs/session_stubs.rb +28 -0
- data/spec/twinfield/api/oauth_session_spec.rb +37 -0
- data/spec/twinfield/api/process_spec.rb +7 -0
- data/spec/twinfield/browse/transaction/cost_center_spec.rb +60 -0
- data/spec/twinfield/browse/transaction/general_ledger_spec.rb +60 -0
- data/spec/twinfield/browse/transaction/transaction_spec.rb +72 -0
- data/spec/twinfield/config_spec.rb +60 -0
- data/spec/twinfield/customer_spec.rb +326 -0
- data/spec/twinfield/request/find_spec.rb +24 -0
- data/spec/twinfield/request/list_spec.rb +58 -0
- data/spec/twinfield/request/read_spec.rb +26 -0
- data/spec/twinfield/sales_invoice_spec.rb +253 -0
- data/spec/twinfield/session_spec.rb +77 -0
- data/spec/twinfield/transaction_spec.rb +149 -0
- data/twinfieldrb.gemspec +24 -0
- data/wsdls/accounting/finder.wsdl +157 -0
- data/wsdls/accounting/process.wsdl +199 -0
- data/wsdls/accounting/session.wsdl +452 -0
- data/wsdls/accounting2/finder.wsdl +157 -0
- data/wsdls/accounting2/process.wsdl +199 -0
- data/wsdls/api.accounting/finder.wsdl +157 -0
- data/wsdls/api.accounting/process.wsdl +199 -0
- data/wsdls/session.wsdl +210 -0
- data/wsdls/update +10 -0
- metadata +196 -0
@@ -0,0 +1,326 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Twinfield::Customer do
|
4
|
+
include SessionStubs
|
5
|
+
include FinderStubs
|
6
|
+
include ProcessxmlStubs
|
7
|
+
|
8
|
+
before do
|
9
|
+
stub_create_session
|
10
|
+
stub_cluster_session_wsdl
|
11
|
+
stub_select_company
|
12
|
+
end
|
13
|
+
|
14
|
+
def stub_customer_ids_request(values)
|
15
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
|
16
|
+
.with(body: /maxRows>10000<\/ma(.*)><string>dimtype<\/string><string>DEB<\/string>/)
|
17
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body>
|
18
|
+
<SearchResponse xmlns="http://www.twinfield.com/"><SearchResult /><data><TotalRows>17</TotalRows><Columns><string>Code</string><string>Naam</string></Columns>
|
19
|
+
<Items>' + values.map { |k, v| "<ArrayOfString><string>#{k}</string><string>#{v}</string></ArrayOfString>" }.join("") + '
|
20
|
+
</Items></data></SearchResponse></soap:Body></soap:Envelope>')
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:existing_customer) do
|
24
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
25
|
+
.with(body: /<dimtype>DEB<\/dimtype>/)
|
26
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/customer/read_success.xml", __FILE__)))
|
27
|
+
Twinfield::Customer.find(1000)
|
28
|
+
end
|
29
|
+
|
30
|
+
describe Twinfield::Customer::Address do
|
31
|
+
describe ".to_s" do
|
32
|
+
it "returns a simple formattable string of the address" do
|
33
|
+
expect(Twinfield::Customer::Address.new(name: "Some Company B.V.", field1: "T.a.v. Jansen", field2: "Berendstraat 12", postcode: "1234AS", city: "Amsterdam", country: "NL").to_s).to eq("Some Company B.V.\nT.a.v. Jansen\nBerendstraat 12\nNL 1234AS Amsterdam")
|
34
|
+
expect(Twinfield::Customer::Address.new(name: "Some Company B.V.", field2: "Berendstraat 12", postcode: "1234AS", city: "Amsterdam", country: "NL").to_s).to eq("Some Company B.V.\nBerendstraat 12\nNL 1234AS Amsterdam")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Twinfield::Customer::Financials do
|
40
|
+
describe ".to_xml" do
|
41
|
+
it "returns a near empty xml when blank" do
|
42
|
+
expect(Twinfield::Customer::Financials.new(level: 2).to_xml).to eq("<financials>\n <level>2</level>\n <meansofpayment>none</meansofpayment>\n</financials>")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#meansofpayment" do
|
47
|
+
it "returns 'none' by default" do
|
48
|
+
expect(Twinfield::Customer::Financials.new.meansofpayment).to eq "none"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#payavailable" do
|
53
|
+
it "returns falsey by default" do
|
54
|
+
expect(Twinfield::Customer::Financials.new.payavailable).to be_falsey
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can be set to true and changes meansofpayment" do
|
58
|
+
new_financials = Twinfield::Customer::Financials.new
|
59
|
+
|
60
|
+
expect(new_financials.meansofpayment).to eq "none"
|
61
|
+
|
62
|
+
new_financials.payavailable = true
|
63
|
+
|
64
|
+
expect(new_financials.payavailable).to be_truthy
|
65
|
+
expect(new_financials.meansofpayment).to eq "paymentfile"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "class methods" do
|
71
|
+
describe ".find" do
|
72
|
+
it "returns a sales invoice" do
|
73
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
74
|
+
.with(body: /<dimtype>DEB<\/dimtype>/)
|
75
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/customer/read_success.xml", __FILE__)))
|
76
|
+
customer = Twinfield::Customer.find(1000)
|
77
|
+
expect(customer.name).to eq("Waardedijk")
|
78
|
+
expect(customer.financials.childvalidations).to eq("1300")
|
79
|
+
expect(customer.addresses[0].default).to eq(true)
|
80
|
+
expect(customer.addresses[0].type).to eq("invoice")
|
81
|
+
expect(customer.modified).to eq DateTime.new(2021, 10, 13, 20, 30, 53)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "deals with an invalid code message" do
|
85
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
86
|
+
.with(body: /<dimtype>DEB<\/dimtype>/)
|
87
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><ProcessXmlStringResponse xmlns="http://www.twinfield.com/"><ProcessXmlStringResult><dimension result="0"><office name="Heden" shortname="">NLA002058</office><type name="Debiteuren" shortname="Debiteuren">DEB</type><code msgtype="error" msg="De code voldoet niet aan het formaat 1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]." result="0">100011</code></dimension></ProcessXmlStringResult></ProcessXmlStringResponse></soap:Body></soap:Envelope>')
|
88
|
+
customer = Twinfield::Customer.find(1000)
|
89
|
+
expect(customer).to be_nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".new" do
|
94
|
+
it "allows to be initialized using a hash" do
|
95
|
+
params = {office: "NLA002058",
|
96
|
+
code: "1004",
|
97
|
+
uid: "c6d17557-dc9b-43ca-92a4-ea07a7627984",
|
98
|
+
name: "De Jong",
|
99
|
+
shortname: "",
|
100
|
+
inuse: "true",
|
101
|
+
behaviour: "normal",
|
102
|
+
modified: Time.now,
|
103
|
+
touched: "1",
|
104
|
+
beginperiod: "0",
|
105
|
+
beginyear: "0",
|
106
|
+
endperiod: "0",
|
107
|
+
endyear: "0",
|
108
|
+
website: "",
|
109
|
+
cocnumber: "",
|
110
|
+
vatnumber: "",
|
111
|
+
financials: {matchtype: "customersupplier",
|
112
|
+
accounttype: "inherit",
|
113
|
+
subanalyse: "false",
|
114
|
+
duedays: "10",
|
115
|
+
level: "2",
|
116
|
+
payavailable: "true",
|
117
|
+
meansofpayment: "paymentfile",
|
118
|
+
paycode: "SEPANLDD",
|
119
|
+
ebilling: true,
|
120
|
+
ebillmail: "test@test.nl",
|
121
|
+
substitutewith: "1300",
|
122
|
+
substitutionlevel: "1",
|
123
|
+
relationsreference: "",
|
124
|
+
vattype: "",
|
125
|
+
vatcode: "",
|
126
|
+
vatobligatory: "false",
|
127
|
+
performancetype: "",
|
128
|
+
collectmandate: {signaturedate: Time.now, id: "1004"},
|
129
|
+
collectionschema: "core",
|
130
|
+
childvalidations: "1300"},
|
131
|
+
creditmanagement: {responsibleuser: "", basecreditlimit: "0.00", sendreminder: "true", reminderemail: "", blocked: "false", freetext1: "", freetext2: "", freetext3: "", comment: ""},
|
132
|
+
remittanceadvice: {sendtype: "ToFileManager", sendmail: ""},
|
133
|
+
addresses: [{name: "De Jong", country: "NL", ictcountrycode: "NL", city: "Rotterdam", postcode: "3012 AF", telephone: "010-6874598", telefax: "", email: "", contact: "", field1: "De heer G. de Jong", field2: "Huizerweg 124a", field3: "", field4: "", field5: "", field6: "", type: "invoice", id: "1", default: "true"}],
|
134
|
+
banks: [{address: {name: "", country: "", ictcountrycode: "", city: "", postcode: "", telephone: "", telefax: "", email: "", contact: "", field1: "", field2: "", field3: "", field4: "", field5: "", field6: "", type: nil, id: nil, default: nil},
|
135
|
+
ascription: "De Jong",
|
136
|
+
accountnumber: "",
|
137
|
+
bankname: "",
|
138
|
+
biccode: "",
|
139
|
+
city: "",
|
140
|
+
country: "NL",
|
141
|
+
iban: "NL30TRIO0123456789",
|
142
|
+
natbiccode: "",
|
143
|
+
postcode: "",
|
144
|
+
state: "",
|
145
|
+
id: "1",
|
146
|
+
default: "true"}],
|
147
|
+
status: "active"}
|
148
|
+
c = Twinfield::Customer.new(**params)
|
149
|
+
expect(c.office).to eq("NLA002058")
|
150
|
+
expect(c.code).to eq("1004")
|
151
|
+
expect(c.addresses.first.city).to eq("Rotterdam")
|
152
|
+
expect(c.financials.collectmandate.id).to eq("1004")
|
153
|
+
expect(c.financials.payavailable).to eq("true")
|
154
|
+
expect(c.banks.first.iban).to eq("NL30TRIO0123456789")
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe ".all" do
|
159
|
+
it "returns a list of customers" do
|
160
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
|
161
|
+
.with(body: /><string>dimtype<\/string><string>DEB<\/string>/)
|
162
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SearchResponse xmlns="http://www.twinfield.com/"><SearchResult /><data><TotalRows>17</TotalRows><Columns><string>Code</string><string>Naam</string></Columns><Items><ArrayOfString><string>1000</string><string>Waardedijk</string></ArrayOfString><ArrayOfString><string>1001</string><string>Witteveen</string></ArrayOfString><ArrayOfString><string>1002</string><string>Bosman</string></ArrayOfString><ArrayOfString><string>1003</string><string>Samkalde</string></ArrayOfString></Items></data></SearchResponse></soap:Body></soap:Envelope>')
|
163
|
+
|
164
|
+
customers = Twinfield::Customer.all
|
165
|
+
expect(customers.length).to eq(4)
|
166
|
+
expect(customers[0]).to be_a Twinfield::Customer
|
167
|
+
expect(customers.map { |a| a.name }).to include("Waardedijk")
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe ".search" do
|
172
|
+
it "accepts a search param" do
|
173
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
|
174
|
+
.with(body: /><string>dimtype<\/string><string>DEB<\/string>/)
|
175
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SearchResponse xmlns="http://www.twinfield.com/"><SearchResult /><data><TotalRows>17</TotalRows><Columns><string>Code</string><string>Naam</string></Columns><Items><ArrayOfString><string>1000</string><string>Waardedijk</string></ArrayOfString><ArrayOfString><string>1001</string><string>Witteveen</string></ArrayOfString><ArrayOfString><string>1002</string><string>Bosman</string></ArrayOfString><ArrayOfString><string>1003</string><string>Samkalde</string></ArrayOfString></Items></data></SearchResponse></soap:Body></soap:Envelope>')
|
176
|
+
|
177
|
+
customers = Twinfield::Customer.search("*Bos*")
|
178
|
+
expect(customers.length).to eq(4)
|
179
|
+
expect(customers[0]).to be_a Twinfield::Customer
|
180
|
+
expect(customers.map { |a| a.name }).to include("Waardedijk")
|
181
|
+
end
|
182
|
+
|
183
|
+
it "deals with no result" do
|
184
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
|
185
|
+
.with(body: /><string>dimtype<\/string><string>DEB<\/string>/)
|
186
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SearchResponse xmlns="http://www.twinfield.com/"><SearchResult /><data><TotalRows>0</TotalRows><Columns><string>Code</string><string>Naam</string></Columns></data></SearchResponse></soap:Body></soap:Envelope>')
|
187
|
+
|
188
|
+
customers = Twinfield::Customer.search("nonexisting")
|
189
|
+
expect(customers.length).to eq(0)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "deals with single result" do
|
193
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/finder.asmx")
|
194
|
+
.with(body: /><string>dimtype<\/string><string>DEB<\/string>/)
|
195
|
+
.to_return(body: '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><SearchResponse xmlns="http://www.twinfield.com/"><SearchResult /><data><TotalRows>1</TotalRows><Columns><string>Code</string><string>Naam</string></Columns><Items><ArrayOfString><string>1002</string><string>Bosman</string></ArrayOfString></Items></data></SearchResponse></soap:Body></soap:Envelope>')
|
196
|
+
|
197
|
+
customers = Twinfield::Customer.search("nonexisting")
|
198
|
+
expect(customers.length).to eq(1)
|
199
|
+
expect(customers[0].name).to eq("Bosman")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe ".next_unused_twinfield_customer_code" do
|
204
|
+
it "returns a new code" do
|
205
|
+
stub_customer_ids_request({"1000": "Waardewijk", "1001": "Witteveen", "1002": "Bosman", "1003": "Samkalde"})
|
206
|
+
expect(Twinfield::Customer.next_unused_twinfield_customer_code).to eq("1004")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "returns a new code" do
|
210
|
+
stub_customer_ids_request({"1000": "Waardewijk", "1001": "Witteveen", "1002": "Bosman", "9003": "Company", "1003": "Samkalde"})
|
211
|
+
expect(Twinfield::Customer.next_unused_twinfield_customer_code).to eq("9004")
|
212
|
+
end
|
213
|
+
|
214
|
+
it "returns a new code within a given range" do
|
215
|
+
stub_customer_ids_request({"1000": "Waardewijk", "1001": "Witteveen", "1002": "Bosman", "9003": "Company", "1003": "Samkalde"})
|
216
|
+
expect(Twinfield::Customer.next_unused_twinfield_customer_code(1000..2000)).to eq("1004")
|
217
|
+
end
|
218
|
+
|
219
|
+
it "returns a new code even when nothing exists in that range" do
|
220
|
+
stub_customer_ids_request({"1000": "Waardewijk", "1001": "Witteveen", "1002": "Bosman", "9003": "Company", "1003": "Samkalde"})
|
221
|
+
expect(Twinfield::Customer.next_unused_twinfield_customer_code(10000..20000)).to eq("10000")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe "instance methods" do
|
227
|
+
describe "#to_h" do
|
228
|
+
it "returns a hash without higher order objects" do
|
229
|
+
stringified_hash = existing_customer.to_h.to_s
|
230
|
+
expect(stringified_hash).not_to match("Twinfield:")
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe "#to_xml" do
|
235
|
+
it "returns returns nokogiri xml" do
|
236
|
+
date = Time.now.to_date
|
237
|
+
collectmandate_id = "4c3f01c582814bc78a8858453392899e"
|
238
|
+
existing_customer.banks << Twinfield::Customer::Bank.new(default: true, accountnumber: 12345678, id: 1)
|
239
|
+
existing_customer.financials.collectmandate = Twinfield::Customer::CollectMandate.new(signaturedate: date, id: collectmandate_id)
|
240
|
+
|
241
|
+
customer_xml = existing_customer.to_xml
|
242
|
+
|
243
|
+
recreated_customer = Twinfield::Customer.from_xml(customer_xml)
|
244
|
+
|
245
|
+
expect(recreated_customer.name).to eq(existing_customer.name)
|
246
|
+
expect(recreated_customer.financials.ebillmail).to eq(existing_customer.financials.ebillmail)
|
247
|
+
expect(recreated_customer.addresses[0].name).to eq(existing_customer.addresses[0].name)
|
248
|
+
expect(recreated_customer.banks[0].accountnumber).to eq("12345678")
|
249
|
+
expect(recreated_customer.financials.collectmandate.signaturedate).to eq(date)
|
250
|
+
end
|
251
|
+
|
252
|
+
it "Twinfield::Customer::Bank doesn't ad an id attribute if id is nil" do
|
253
|
+
b = Twinfield::Customer::Bank.new(default: true, iban: 12345678)
|
254
|
+
expect(b.to_xml).to match("default=\"true\"")
|
255
|
+
expect(b.to_xml).not_to match("id=\"\"")
|
256
|
+
end
|
257
|
+
|
258
|
+
it "Twinfield::Customer::CollectMandate.to_xml" do
|
259
|
+
date = Time.now.to_date
|
260
|
+
collectmandate_id = "4c3f01c582814bc78a8858453392899e"
|
261
|
+
|
262
|
+
cm = Twinfield::Customer::CollectMandate.new(signaturedate: date, id: collectmandate_id)
|
263
|
+
expect(cm.to_xml).to match("<id>4c3f01c582814bc78a8858453392899e</id>")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "#transactions" do
|
268
|
+
it "returns Twinfield::Browse::Transaction::Customers" do
|
269
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
270
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
|
271
|
+
|
272
|
+
customer = Twinfield::Customer.new(name: "Maarten Brouwers", code: "1003")
|
273
|
+
transaction = customer.transactions.first
|
274
|
+
|
275
|
+
expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
|
276
|
+
expect(transaction.value).to eql(2200.0)
|
277
|
+
end
|
278
|
+
|
279
|
+
it "allows for filtering" do
|
280
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
281
|
+
.with(body: /<from>VRFK<\/from>/)
|
282
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/columns/sales_transactions.xml", __FILE__)))
|
283
|
+
|
284
|
+
customer = Twinfield::Customer.new(name: "Maarten Brouwers", code: "1003")
|
285
|
+
transaction = customer.transactions(code: "VRFK").first
|
286
|
+
|
287
|
+
expect(transaction).to be_a(Twinfield::Browse::Transaction::Customer)
|
288
|
+
expect(transaction.value).to eql(2200.0)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe "#save" do
|
293
|
+
it "saves a new record" do
|
294
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
295
|
+
.with(body: /Maarten Brouwers/)
|
296
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/customer/create_success.xml", __FILE__)))
|
297
|
+
|
298
|
+
customer = Twinfield::Customer.new(name: "Maarten Brouwers", code: "1200")
|
299
|
+
customer = customer.save
|
300
|
+
expect(customer.name).to eq("Maarten Brouwers")
|
301
|
+
expect(customer.uid).to eq("ece29a7f-344f-4e37-b5ca-53e2a468070e")
|
302
|
+
end
|
303
|
+
|
304
|
+
it "updates a record" do
|
305
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
306
|
+
.with(body: /Maarten Brouwers/)
|
307
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/customer/create_success.xml", __FILE__)))
|
308
|
+
|
309
|
+
customer = Twinfield::Customer.new(name: "Maarten Brouwers", code: "1200")
|
310
|
+
customer = customer.save
|
311
|
+
expect(customer.name).to eq("Maarten Brouwers")
|
312
|
+
expect(customer.uid).to eq("ece29a7f-344f-4e37-b5ca-53e2a468070e")
|
313
|
+
expect(customer.shortname).to eq("")
|
314
|
+
|
315
|
+
customer.shortname = "murb"
|
316
|
+
|
317
|
+
stub_request(:post, "https://accounting.twinfield.com/webservices/processxml.asmx")
|
318
|
+
.with(body: /ece29a7f-344f-4e37-b5ca-53e2a468070e/)
|
319
|
+
.to_return(body: File.read(File.expand_path("../../fixtures/cluster/processxml/customer/update_success.xml", __FILE__)))
|
320
|
+
|
321
|
+
customer = customer.save
|
322
|
+
expect(customer.shortname).to eq("murb")
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Twinfield::Request::Find do
|
4
|
+
include SessionStubs
|
5
|
+
include FinderStubs
|
6
|
+
|
7
|
+
context "Twinfield::Api::Session" do
|
8
|
+
before do
|
9
|
+
stub_create_session
|
10
|
+
stub_cluster_session_wsdl
|
11
|
+
stub_select_company
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#sales_transactions" do
|
15
|
+
it "returns 100 sales transactions" do
|
16
|
+
stub_finder("IVT")
|
17
|
+
expect(Twinfield::Request::Find.sales_transactions.count).to eq(100)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#debtor" do
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Twinfield::Request::List do
|
4
|
+
include SessionStubs
|
5
|
+
include ProcessxmlStubs
|
6
|
+
|
7
|
+
context "Twinfield::Api::Session" do
|
8
|
+
before do
|
9
|
+
stub_create_session
|
10
|
+
stub_cluster_session_wsdl
|
11
|
+
stub_select_company
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#dimensions" do
|
15
|
+
it "lists debtors" do
|
16
|
+
stub_processxml_list_dimensions(dimension_type: "DEB", company: "company")
|
17
|
+
expect(subject.dimensions({dimtype: "DEB"})).to be_a Nokogiri::XML::Document
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "Twinfield::Api::OAuthSession" do
|
23
|
+
before do
|
24
|
+
#
|
25
|
+
# stub_cluster_session_wsdl
|
26
|
+
|
27
|
+
Twinfield.configure do |config|
|
28
|
+
config.session_type = "Twinfield::Api::OAuthSession"
|
29
|
+
config.cluster = "https://accounting.twinfield.com"
|
30
|
+
config.access_token = "2b128baa05dd3cabc61e534435884961"
|
31
|
+
# config.log_level = :debug
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
after do
|
36
|
+
Twinfield.configure do |config|
|
37
|
+
config.session_type = nil
|
38
|
+
config.cluster = nil
|
39
|
+
config.access_token = nil
|
40
|
+
config.log_level = nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#dimensions" do
|
45
|
+
it "lists debtors" do
|
46
|
+
stub_processxml_list_dimensions(dimension_type: "DEB", oauth: true)
|
47
|
+
expect(subject.dimensions({dimtype: "DEB"})).to be_a Nokogiri::XML::Document
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#offices" do
|
52
|
+
it "lists offices" do
|
53
|
+
stub_processxml_list_offices(oauth: true)
|
54
|
+
# expect(subject.offices).to be_a Nokogiri::XML::Document
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Twinfield::Request::Read do
|
4
|
+
include SessionStubs
|
5
|
+
include ProcessxmlStubs
|
6
|
+
|
7
|
+
describe ".xml_to_nokogiri" do
|
8
|
+
it "works for simple xml" do
|
9
|
+
expect(Twinfield::Request::Read.xml_to_json(Nokogiri::XML("<items><item><value>1</value><key>Something</key></item></items>"))).to eq(items: [{
|
10
|
+
value: 1, key: "Something"
|
11
|
+
}])
|
12
|
+
expect(Twinfield::Request::Read.xml_to_json(Nokogiri::XML("<prog>
|
13
|
+
<prog_name>Barclay CTA Index</prog_name>
|
14
|
+
<prog_id>9</prog_id>
|
15
|
+
</prog>"))).to eq(prog: {prog_id: 9, prog_name: "Barclay CTA Index"})
|
16
|
+
end
|
17
|
+
it "works for an invoice" do
|
18
|
+
invoice_response = File.read(File.expand_path("../../../fixtures/cluster/processxml/invoice/create_success.xml", __FILE__))
|
19
|
+
hash = Twinfield::Request::Read.xml_to_json(Nokogiri::XML(Nokogiri::XML(invoice_response).remove_namespaces!.xpath("//ProcessXmlStringResult").text))
|
20
|
+
expect(hash[:salesinvoice].keys).to include :header
|
21
|
+
expect(hash[:salesinvoice][:header][:invoicenumber]).to eq(3)
|
22
|
+
expect(hash[:salesinvoice][:lines].count).to eq(1)
|
23
|
+
expect(hash[:salesinvoice][:lines][0][:article]).to eq("A")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|