twinfieldrb 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/codeql-analysis.yml +70 -0
  3. data/.github/workflows/rspec.yml +33 -0
  4. data/.gitignore +6 -0
  5. data/.rspec +1 -0
  6. data/CHANGELOG.md +15 -0
  7. data/Gemfile +4 -0
  8. data/README.md +120 -0
  9. data/Rakefile +1 -0
  10. data/lib/twinfield/abstract_model.rb +7 -0
  11. data/lib/twinfield/api/base_api.rb +50 -0
  12. data/lib/twinfield/api/finder.rb +45 -0
  13. data/lib/twinfield/api/o_auth_session.rb +58 -0
  14. data/lib/twinfield/api/process.rb +44 -0
  15. data/lib/twinfield/api/session.rb +170 -0
  16. data/lib/twinfield/browse/transaction/cost_center.rb +145 -0
  17. data/lib/twinfield/browse/transaction/customer.rb +413 -0
  18. data/lib/twinfield/browse/transaction/general_ledger.rb +144 -0
  19. data/lib/twinfield/configuration.rb +49 -0
  20. data/lib/twinfield/create/cost_center.rb +39 -0
  21. data/lib/twinfield/create/creditor.rb +88 -0
  22. data/lib/twinfield/create/debtor.rb +88 -0
  23. data/lib/twinfield/create/error.rb +30 -0
  24. data/lib/twinfield/create/general_ledger.rb +39 -0
  25. data/lib/twinfield/create/transaction.rb +97 -0
  26. data/lib/twinfield/customer.rb +612 -0
  27. data/lib/twinfield/helpers/parsers.rb +23 -0
  28. data/lib/twinfield/helpers/transaction_match.rb +40 -0
  29. data/lib/twinfield/request/find.rb +149 -0
  30. data/lib/twinfield/request/list.rb +66 -0
  31. data/lib/twinfield/request/read.rb +111 -0
  32. data/lib/twinfield/sales_invoice.rb +409 -0
  33. data/lib/twinfield/transaction.rb +112 -0
  34. data/lib/twinfield/version.rb +5 -0
  35. data/lib/twinfield.rb +89 -0
  36. data/script/boot.rb +58 -0
  37. data/script/console +2 -0
  38. data/spec/fixtures/cluster/finder/ivt.xml +1 -0
  39. data/spec/fixtures/cluster/processxml/columns/sales_transactions.xml +312 -0
  40. data/spec/fixtures/cluster/processxml/customer/create_success.xml +100 -0
  41. data/spec/fixtures/cluster/processxml/customer/read_success.xml +93 -0
  42. data/spec/fixtures/cluster/processxml/customer/update_success.xml +1 -0
  43. data/spec/fixtures/cluster/processxml/invoice/create_error.xml +8 -0
  44. data/spec/fixtures/cluster/processxml/invoice/create_final_error.xml +67 -0
  45. data/spec/fixtures/cluster/processxml/invoice/create_success.xml +64 -0
  46. data/spec/fixtures/cluster/processxml/invoice/read_not_found.xml +1 -0
  47. data/spec/fixtures/cluster/processxml/invoice/read_success.xml +106 -0
  48. data/spec/fixtures/cluster/processxml/read/deb.xml +12 -0
  49. data/spec/fixtures/cluster/processxml/response.xml +8 -0
  50. data/spec/fixtures/login/session/wsdl.xml +210 -0
  51. data/spec/spec_helper.rb +17 -0
  52. data/spec/stubs/finder_stubs.rb +19 -0
  53. data/spec/stubs/processxml_stubs.rb +41 -0
  54. data/spec/stubs/session_stubs.rb +28 -0
  55. data/spec/twinfield/api/oauth_session_spec.rb +37 -0
  56. data/spec/twinfield/api/process_spec.rb +7 -0
  57. data/spec/twinfield/browse/transaction/cost_center_spec.rb +60 -0
  58. data/spec/twinfield/browse/transaction/general_ledger_spec.rb +60 -0
  59. data/spec/twinfield/browse/transaction/transaction_spec.rb +72 -0
  60. data/spec/twinfield/config_spec.rb +60 -0
  61. data/spec/twinfield/customer_spec.rb +326 -0
  62. data/spec/twinfield/request/find_spec.rb +24 -0
  63. data/spec/twinfield/request/list_spec.rb +58 -0
  64. data/spec/twinfield/request/read_spec.rb +26 -0
  65. data/spec/twinfield/sales_invoice_spec.rb +253 -0
  66. data/spec/twinfield/session_spec.rb +77 -0
  67. data/spec/twinfield/transaction_spec.rb +149 -0
  68. data/twinfieldrb.gemspec +24 -0
  69. data/wsdls/accounting/finder.wsdl +157 -0
  70. data/wsdls/accounting/process.wsdl +199 -0
  71. data/wsdls/accounting/session.wsdl +452 -0
  72. data/wsdls/accounting2/finder.wsdl +157 -0
  73. data/wsdls/accounting2/process.wsdl +199 -0
  74. data/wsdls/api.accounting/finder.wsdl +157 -0
  75. data/wsdls/api.accounting/process.wsdl +199 -0
  76. data/wsdls/session.wsdl +210 -0
  77. data/wsdls/update +10 -0
  78. 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>&lt;dimension result="0"&gt;&lt;office name="Heden" shortname=""&gt;NLA002058&lt;/office&gt;&lt;type name="Debiteuren" shortname="Debiteuren"&gt;DEB&lt;/type&gt;&lt;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"&gt;100011&lt;/code&gt;&lt;/dimension&gt;</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