dpd_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +468 -0
  7. data/Rakefile +2 -0
  8. data/dpd_api.gemspec +26 -0
  9. data/lib/dpd_api/base.rb +36 -0
  10. data/lib/dpd_api/calculator.rb +21 -0
  11. data/lib/dpd_api/configuration.rb +33 -0
  12. data/lib/dpd_api/geography.rb +26 -0
  13. data/lib/dpd_api/label_print.rb +32 -0
  14. data/lib/dpd_api/nl.rb +32 -0
  15. data/lib/dpd_api/order.rb +56 -0
  16. data/lib/dpd_api/tracing.rb +26 -0
  17. data/lib/dpd_api/version.rb +3 -0
  18. data/lib/dpd_api.rb +14 -0
  19. data/spec/fixtures/dpd_api/calculator/service_cost.xml +55 -0
  20. data/spec/fixtures/dpd_api/calculator/service_cost_by_parcels.xml +55 -0
  21. data/spec/fixtures/dpd_api/calculator/service_cost_by_parcels_fault.xml +15 -0
  22. data/spec/fixtures/dpd_api/calculator/service_cost_fault.xml +15 -0
  23. data/spec/fixtures/dpd_api/geography/cities_cash_pay.xml +23 -0
  24. data/spec/fixtures/dpd_api/geography/parcel_shops.xml +39 -0
  25. data/spec/fixtures/dpd_api/geography/terminals_self_delivery.xml +35 -0
  26. data/spec/fixtures/dpd_api/order/add_parcels.xml +0 -0
  27. data/spec/fixtures/dpd_api/order/cancel_order.xml +11 -0
  28. data/spec/fixtures/dpd_api/order/create_address.xml +11 -0
  29. data/spec/fixtures/dpd_api/order/create_order.xml +14 -0
  30. data/spec/fixtures/dpd_api/order/invoice_file.xml +0 -0
  31. data/spec/fixtures/dpd_api/order/order_status.xml +12 -0
  32. data/spec/fixtures/dpd_api/order/remove_parcels.xml +0 -0
  33. data/spec/fixtures/dpd_api/order/update_address.xml +11 -0
  34. data/spec/fixtures/dpd_api/tracing/states_by_client_order.xml +0 -0
  35. data/spec/fixtures/dpd_api/tracing/states_by_client_parcel.xml +0 -0
  36. data/spec/fixtures/dpd_api/tracing/states_by_dpd_order.xml +0 -0
  37. data/spec/lib/dpd_api/calculator_spec.rb +99 -0
  38. data/spec/lib/dpd_api/configuration_spec.rb +23 -0
  39. data/spec/lib/dpd_api/geography_spec.rb +53 -0
  40. data/spec/lib/dpd_api/order_spec.rb +200 -0
  41. data/spec/lib/dpd_api/tracing_spec.rb +58 -0
  42. data/spec/spec_helper.rb +7 -0
  43. metadata +165 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ffa837bb809c1d46862490d923d3d4543cf2591
4
+ data.tar.gz: 88a31b5250ee6a8cfc3d7f10dc61a09846bd4594
5
+ SHA512:
6
+ metadata.gz: 79e3ac96bff1fb10d51ec69b4f4e59b1f44a2eefd4d85eadad9b4f75bcf9424d34f05e78a7af949512d1d7a4ee88e9d5986201dd3eb1dfa4542b4ab3174946b5
7
+ data.tar.gz: 378cbf3c5335192b3ebad252e219cae5e931bf5baea4afeb73a68f7809f28158ccb04685177bfc56e5d40220fb5d0e1243845d640eaf2ff7f84d9ef78d7d483d
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in dpd_api.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ponomarev Nikolay
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,468 @@
1
+ DpdApi
2
+ ======
3
+
4
+ :small_red_triangle_down: Ruby implementation for [DPD](http://dpd.ru)'s SOAP API
5
+
6
+ Installation
7
+ ------------
8
+
9
+ ### Rails
10
+
11
+ ```ruby
12
+ # Gemfile
13
+ gem 'dpd_api'
14
+ ```
15
+
16
+ ```ruby
17
+ # config/initializers/dpd_api.rb
18
+ DpdApi.configure do |config|
19
+ # your dpd's given client key and client number
20
+ config.client_key = 'ASD7686ASD76786786786786AASD'
21
+ config.client_number = '123456789'
22
+ config.base_url = Rails.env.production? ? 'http://ws.dpd.ru' : 'http://wstest.dpd.ru'
23
+ end
24
+ ```
25
+
26
+ ### Ruby
27
+ ```ruby
28
+ gem install dpd_api
29
+ ```
30
+
31
+ ```ruby
32
+ require 'dpd_api'
33
+
34
+ client_key = 'ASD7686ASD76786786786786AASD'
35
+ client_number = '123456789'
36
+ DpdApi.configure { |c| c.client_key = client_key; c.client_number = client_number; }
37
+ ```
38
+
39
+ Quickstart
40
+ ----------
41
+
42
+ ```ruby
43
+ params = { pickup: { city_id: 195851995 },
44
+ delivery: { city_id: 48951627 },
45
+ self_pickup: false,
46
+ self_delivery: false,
47
+ weight: 1, }
48
+
49
+ DpdApi::Calculator.service_cost(params)
50
+
51
+ #=> [{:service_code=>"TEN", :service_name=>"DPD 10:00", :cost=>"2228.67", :days=>"4"}, {:service_code=>"DPT", :service_name=>"DPD 13:00", :cost=>"1966.47", :days=>"4"}, . . .]
52
+ ```
53
+
54
+ Getting started
55
+ ---------------
56
+
57
+ ### DpdApi::Geography
58
+ matches `/services/geography?wsdl` in DPD SOAP API
59
+
60
+ ####.cities_cash_pay
61
+ matches `getCitiesCashPay`
62
+ ```ruby
63
+ DpdApi::Geography.cities_cash_pay
64
+
65
+ # => [{
66
+ city_id: "48951627",
67
+ country_code: "RU",
68
+ country_name: "Россия",
69
+ region_code: "42",
70
+ region_name: "Кемеровская",
71
+ city_name: "Кемерово"
72
+ }, . . . ]
73
+
74
+ ```
75
+
76
+ ####.terminals_self_delivery
77
+ matches `getTerminalsSelfDelivery2`
78
+ ```ruby
79
+ DpdApi::Geography.terminals_self_delivery
80
+
81
+ # => [{
82
+ terminal: {
83
+ terminal_code: "ABA",
84
+ terminal_name: "Абакан - терминал",
85
+ terminal_address: "655004, Хакасия респ., г. Абакан, ул. Игарская, д. 10",
86
+ geo_coordinates: {
87
+ geo_x: "53.710113",
88
+ geo_y: "91.392873"
89
+ },
90
+ working_time: {
91
+ week_days: "Пн,Вт,Ср,Чт,Пт,Сб,Вс",
92
+ work_time: "09:00 - 18:00"
93
+ }
94
+ },
95
+ city: {
96
+ city_id: "195851995",
97
+ country_code: "RU",
98
+ country_name: "Россия",
99
+ region_code: "19",
100
+ region_name: "Хакасия",
101
+ city_code: "19000001000",
102
+ city_name: "Абакан"
103
+ }
104
+ }, . . . ]
105
+
106
+ ```
107
+
108
+ ####.parcel_shops
109
+ matches `?` there's no method in documentation
110
+ ```ruby
111
+ params = {} # or without
112
+ DpdApi::Geography.parcel_shops(params)
113
+
114
+ # => [{
115
+ code: "01A",
116
+ parcel_shop_type: "ПВП",
117
+ address: {
118
+ country_code: "RU",
119
+ region_code: "61",
120
+ region_name: "Ростовская",
121
+ city_code: "61000001000",
122
+ city_name: "Ростов-на-Дону",
123
+ address_string: "344038, Ростовская обл., г. Ростов-на-Дону, пр-т Ленина, д. 115"
124
+ },
125
+ geo_coordinates: {
126
+ geo_x: "47.249054",
127
+ geo_y: "39.722657"
128
+ },
129
+ limits: {
130
+ max_weight: "31",
131
+ max_length: "100",
132
+ max_width: "100",
133
+ max_height: "100"
134
+ },
135
+ working_time: [
136
+ {
137
+ week_days: "Пн,Вт,Ср,Чт,Пт,Сб",
138
+ work_time: "09:00 - 20:00"
139
+ },
140
+ {
141
+ week_days: "Вс",
142
+ work_time: "выходной"
143
+ }
144
+ ]
145
+ }, . . . ]
146
+
147
+ ```
148
+
149
+ ### DpdApi::Calculator
150
+ matches `/services/calculator2?wsdl` in DPD SOAP API
151
+
152
+ ####.service_cost
153
+ matches `getSeviceCost2`
154
+ ```ruby
155
+ params = { pickup: { city_id: 195851995 },
156
+ delivery: { city_id: 48951627 },
157
+ self_pickup: false,
158
+ self_delivery: false,
159
+ weight: 1, }
160
+
161
+ DpdApi::Geography.service_cost(params)
162
+
163
+ # => [{
164
+ service_code: "TEN",
165
+ service_name: "DPD 10:00",
166
+ cost: "2228.67",
167
+ days: "4"
168
+ }, . . . ]
169
+
170
+ ```
171
+
172
+ ####.service_cost_by_parcels
173
+ matches `getServiceCostByParcels2`
174
+ ```ruby
175
+ params = {
176
+ pickup: { city_id: 195851995 },
177
+ delivery: { city_id: 48951627 },
178
+ self_pickup: true,
179
+ self_delivery: true,
180
+ parcel: {
181
+ weight: 0.5,
182
+ length: 0.5,
183
+ width: 0.5,
184
+ height: 0.5,
185
+ },
186
+ parcel: {
187
+ weight: 1,
188
+ length: 1,
189
+ width: 1,
190
+ height: 1,
191
+ },
192
+ }
193
+
194
+ DpdApi::Geography.service_cost_by_parcels(params)
195
+
196
+ # => [{
197
+ service_code: "TEN",
198
+ service_name: "DPD 10:00",
199
+ cost: "551.65",
200
+ days: "4"
201
+ }, . . . ]
202
+
203
+ ```
204
+
205
+ ### DpdApi::Order
206
+ matches `/services/order2?wsdl`
207
+
208
+ ####.create_order
209
+ matches `createOrder`
210
+ ```ruby
211
+ params = {
212
+ header: {
213
+ date_pickup: date,
214
+ sender_address: {
215
+ name: fio,
216
+ terminal_code: 'ABA',
217
+ city: 'Москва',
218
+ street: 'Ленина',
219
+ street_abbr: 'ул',
220
+ house: 1,
221
+ contact_fio: fio,
222
+ contact_phone: '+79211234567',
223
+ },
224
+ },
225
+ order: [
226
+ {
227
+ order_number_internal: '1234567',
228
+ service_code: 'TEN',
229
+ service_variant: 'ТД',
230
+ cargo_num_pack: '1',
231
+ cargo_weight: '1',
232
+ cargo_registered: false,
233
+ cargo_category: 'Одежда',
234
+ receiver_address: {
235
+ name: fio,
236
+ terminal_code: '',
237
+ city: 'Воронеж',
238
+ street: 'Красноармейская',
239
+ street_abbr: 'ул',
240
+ house: 1,
241
+ contact_fio: fio,
242
+ contact_phone: '+79211234567',
243
+ },
244
+ parcel: [
245
+ {
246
+ number: '123456789',
247
+ },
248
+ ],
249
+ },
250
+ ],
251
+ }
252
+
253
+ DpdApi::Order.create_order(params)
254
+
255
+ # => [{
256
+ order_number_internal: "1234567",
257
+ order_num: "10160002MOW",
258
+ status: "OK",
259
+ error_message: nil,
260
+ }]
261
+
262
+ ```
263
+
264
+ ####.order_status
265
+ matches `getOrderStatus`
266
+ ```ruby
267
+ params = {
268
+ order: {
269
+ order_number_internal: '123456',
270
+ }
271
+ }
272
+
273
+
274
+ DpdApi::Order.order_status(params)
275
+
276
+ # => [{
277
+ order_number_internal: "123456",
278
+ order_num: "10160001MOW",
279
+ status: "OK",
280
+ }]
281
+
282
+
283
+ ```
284
+ ####.create_address
285
+ matches `createAddress`
286
+ ```ruby
287
+ params = {
288
+ client_address: {
289
+ code: '78',
290
+ name: fio,
291
+ city: 'Воронеж',
292
+ street: 'Красноармейская',
293
+ street_abbr: 'ул',
294
+ house: 1,
295
+ contact_fio: fio,
296
+ contact_phone: '+79211234567',
297
+ },
298
+ }
299
+
300
+
301
+
302
+ DpdApi::Order.create_address(params)
303
+
304
+ # => [{
305
+ code: "78",
306
+ status: "OK",
307
+ }]
308
+
309
+
310
+ ```
311
+ ####.update_address
312
+ matches `updateAddress`
313
+ ```ruby
314
+ params = {
315
+ client_address: {
316
+ code: '78',
317
+ name: fio,
318
+ city: 'Воронеж',
319
+ street: 'Красноармейская',
320
+ street_abbr: 'ул',
321
+ house: 1,
322
+ contact_fio: fio,
323
+ contact_phone: '+79200000000',
324
+ },
325
+ }
326
+
327
+
328
+
329
+
330
+ DpdApi::Order.update_address(params)
331
+
332
+ # => [{
333
+ code: "78",
334
+ status: "OK",
335
+ }]
336
+ ```
337
+
338
+ ####.cancel_order
339
+ matches `cancelOrder`
340
+ ```ruby
341
+ params = {
342
+ cancel: {
343
+ order_num: '10160001MOW',
344
+ },
345
+ }
346
+
347
+ DpdApi::Order.cancel_order(params)
348
+
349
+ # => [{
350
+ order_number_internal: "123456",
351
+ order_num: "10160001MOW",
352
+ status: "Canceled",
353
+ }]
354
+
355
+ ```
356
+
357
+ ####.add_parcels
358
+ matches `addParcels`
359
+ ```ruby
360
+ params = {
361
+ order_num: '10160001MOW',
362
+ cargo_num_pack: '2',
363
+ cargo_weight: '2',
364
+ cargo_category: 'Одежда',
365
+ parcel: [
366
+ { number: '987654321' },
367
+ { number: '5678' },
368
+ ],
369
+ }
370
+
371
+ DpdApi::Order.add_parcels(params)
372
+
373
+ # => {
374
+ order_num: "10160001MOW",
375
+ status: "OK",
376
+ parcel_status: [
377
+ {
378
+ number: "987654321",
379
+ status: "OK",
380
+ },
381
+ {
382
+ number: "5678",
383
+ status: "OK"
384
+ }
385
+ ]
386
+ }
387
+
388
+ ```
389
+
390
+ ####.remove_parcels
391
+ matches `removeParcels`
392
+ ```ruby
393
+ params = {
394
+ order_num: '10160001MOW',
395
+ cargo_num_pack: '1',
396
+ cargo_weight: '1',
397
+ cargo_category: 'Одежда',
398
+ parcel: [
399
+ {
400
+ number: '987654321',
401
+ },
402
+ ],
403
+ }
404
+
405
+
406
+ DpdApi::Order.remove_parcels(params)
407
+
408
+ # => {
409
+ order_num: "10160001MOW",
410
+ status: "OK",
411
+ parcel_status: {
412
+ number: "987654321",
413
+ status: "OK",
414
+ },
415
+ }
416
+
417
+
418
+ ```
419
+
420
+
421
+ ####.invoice_file
422
+ matches `getInvoiceFile`
423
+ ```ruby
424
+ params = { order_num: '10160002MOW' }
425
+
426
+ DpdApi::Order.invoice_file(params)
427
+
428
+ # => {
429
+ file: 'JVBERi0xLjQKJeLj . . .'
430
+ }
431
+ ```
432
+
433
+
434
+ ### DpdApi::Tracing
435
+ matches `/services/tracing1-1?wsdl` in DPD SOAP API
436
+
437
+ ####.states_by_client_order
438
+ matches `getStatesByClientOrder`
439
+ ```ruby
440
+ params = {
441
+ client_order_nr: '12345',
442
+ }
443
+
444
+ DpdApi::Tracing.states_by_client_order(params)
445
+
446
+ ```
447
+
448
+ ####.states_by_client_parcel
449
+ matches `getStatesByClientParcel`
450
+ ```ruby
451
+ params = {
452
+ client_parcel_nr: '987654321',
453
+ }
454
+
455
+ DpdApi::Tracing.states_by_client_parcel(params)
456
+
457
+ ```
458
+
459
+ ####.states_by_dpd_order
460
+ matches `getStatesByDpdOrder`
461
+ ```ruby
462
+ params = {
463
+ client_parcel_nr: '987654321',
464
+ }
465
+
466
+ DpdApi::Tracing.states_by_dpd_order(params)
467
+
468
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/dpd_api.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dpd_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dpd_api"
8
+ spec.version = DpdApi::VERSION
9
+ spec.authors = ["Ponomarev Nikolay"]
10
+ spec.email = ["itsnikolay@gmail.com"]
11
+ spec.summary = %q{Ruby API for Dpd delivery service}
12
+ spec.description = %q{Ruby API for Dpd delivery service}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency 'savon', "~> 2.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec"
26
+ end
@@ -0,0 +1,36 @@
1
+ module DpdApi
2
+ class Base
3
+ class << self
4
+ def operations
5
+ client.operations
6
+ end
7
+
8
+ protected
9
+
10
+ def client
11
+ Savon.client(wsdl: self.url)
12
+ end
13
+
14
+ def response(method, params = {})
15
+ begin
16
+ params = DpdApi.configuration
17
+ .auth_params
18
+ .clone
19
+ .deep_merge!(params)
20
+ request = params.blank? ? params : { request: params }
21
+ response = client.call(method, message: request)
22
+ namespace = "#{method}_response".to_sym
23
+ resources = response.body[namespace][:return]
24
+ resources = if resources.is_a?(Array)
25
+ resources
26
+ else
27
+ [] << resources
28
+ end
29
+ resources
30
+ rescue Savon::SOAPFault => error
31
+ { errors: error.to_s }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ module DpdApi
2
+ class Calculator < Base
3
+ class << self
4
+ def service_cost(params = {})
5
+ method = :get_service_cost2
6
+ response(method, params)
7
+ end
8
+
9
+ def service_cost_by_parcels(params = {})
10
+ method = :get_service_cost_by_parcels2
11
+ response(method, params)
12
+ end
13
+
14
+ protected
15
+
16
+ def url
17
+ "#{DpdApi.configuration.base_url}/services/calculator2?wsdl"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module DpdApi
2
+ class << self
3
+ attr_accessor :configuration
4
+ end
5
+
6
+ def self.configure
7
+ self.configuration ||= Configuration.new
8
+ yield(configuration)
9
+ end
10
+
11
+ class Configuration
12
+ attr_accessor :client_key,
13
+ :client_number,
14
+ :base_url
15
+
16
+ attr_reader :auth_params
17
+
18
+ def initialize
19
+ @client_key = '123'
20
+ @client_number = '234'
21
+ @base_url = 'http://wstest.dpd.ru'
22
+ end
23
+
24
+ def auth_params
25
+ {
26
+ auth: {
27
+ client_number: client_number,
28
+ client_key: client_key,
29
+ }
30
+ }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module DpdApi
2
+ class Geography < Base
3
+ class << self
4
+ def cities_cash_pay
5
+ method = :get_cities_cash_pay
6
+ response(method)
7
+ end
8
+
9
+ def terminals_self_delivery
10
+ method = :get_terminals_self_delivery2
11
+ response(method)
12
+ end
13
+
14
+ def parcel_shops(params = {})
15
+ method = :get_parcel_shops
16
+ response(method, params)
17
+ end
18
+
19
+ protected
20
+
21
+ def url
22
+ "#{DpdApi.configuration.base_url}/services/geography?wsdl"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ module DpdApi
2
+ class LabelPrint < Base
3
+ # TODO: Implement namespace
4
+ class << self
5
+ def create_label_file(params = {})
6
+ method = :create_label_file
7
+ namespace = :get_label_file
8
+ response(method, params, namespace: namespace)
9
+ end
10
+
11
+ def create_label(params = {})
12
+ method = :create_label
13
+ namespace = :get_label
14
+ response(method, params, namespace: namespace)
15
+ end
16
+
17
+ def response(method, params = {}, namespace: nil)
18
+ params = @auth_params.clone.deep_merge!(params)
19
+ request = namespace ? { namespace => params } : params
20
+ response = @client.call(method, message: request)
21
+ namespace = "#{method}_response".to_sym
22
+ response.body[namespace][:return]
23
+ end
24
+
25
+ protected
26
+
27
+ def url
28
+ "#{DpdApi.configuration.base_url}/services/label-print?wsdl"
29
+ end
30
+ end
31
+ end
32
+ end