twinfieldrb 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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