dhl-ecommerce 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +112 -0
- data/lib/dhl-ecommerce.rb +89 -0
- data/lib/dhl/ecommerce/account.rb +30 -0
- data/lib/dhl/ecommerce/base.rb +22 -0
- data/lib/dhl/ecommerce/errors/authentication_error.rb +8 -0
- data/lib/dhl/ecommerce/errors/base_error.rb +15 -0
- data/lib/dhl/ecommerce/errors/validation_error.rb +8 -0
- data/lib/dhl/ecommerce/event.rb +18 -0
- data/lib/dhl/ecommerce/impb.rb +7 -0
- data/lib/dhl/ecommerce/label.rb +250 -0
- data/lib/dhl/ecommerce/location.rb +24 -0
- data/lib/dhl/ecommerce/manifest.rb +54 -0
- data/lib/dhl/ecommerce/operations/find.rb +18 -0
- data/lib/dhl/ecommerce/operations/list.rb +19 -0
- data/lib/dhl/ecommerce/product.rb +34 -0
- data/lib/dhl/ecommerce/standard_address.rb +20 -0
- data/lib/dhl/ecommerce/tracked_event.rb +18 -0
- data/lib/dhl/ecommerce/version.rb +5 -0
- data/spec/account_spec.rb +11 -0
- data/spec/cassettes/api_dhlglobalmail_com.yml +381 -0
- data/spec/errors/authentication_error_spec.rb +9 -0
- data/spec/event_spec.rb +11 -0
- data/spec/label_spec.rb +30 -0
- data/spec/location_spec.rb +11 -0
- data/spec/product_spec.rb +11 -0
- data/spec/spec_helper.rb +36 -0
- metadata +234 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9fdcd2715365cddaefd2c83251042ead98c90bc4
|
4
|
+
data.tar.gz: cd2b1f3aa0c60ded06018d0061a62fe4cb6b0b74
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 171ad8b6de6315759b2bda5af0addc55c32d031070ad5e2067013de9136d7cf7b0594826411d9e34fac36431240cc7eea41e77983554b8b1766166d4ceba0f11
|
7
|
+
data.tar.gz: 5eb55a54b412c6e6a34129b97dc979b53051c7c2000ece228e742fc3a934e415122352532fa4dce376078dbda397daf4fbbf33b353a015dd714bf9ae47886aaa
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 meowbox Inc.
|
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,112 @@
|
|
1
|
+
# DHL eCommerce API Wrapper for Ruby
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/meowbox/dhl-ecommerce-ruby.svg)](https://travis-ci.org/meowbox/dhl-ecommerce-ruby)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Installation is as simple at adding the following to your `Gemfile`.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "dhl-ecommerce"
|
11
|
+
```
|
12
|
+
|
13
|
+
## Configuration
|
14
|
+
|
15
|
+
The only configuration necessary is your `client_id` and either a `username`
|
16
|
+
and `password` or an `access_token`.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
# DHL e-Commerce configuration.
|
20
|
+
DHL::Ecommerce.configure do |config|
|
21
|
+
config.username = "meowbox"
|
22
|
+
config.password = "password"
|
23
|
+
config.client_id = 6369
|
24
|
+
|
25
|
+
# Label format can be either :png or :zpl.
|
26
|
+
config.label_format = :png
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
### Accounts
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# Find all accounts.
|
36
|
+
accounts = DHL::Ecommerce::Account.all
|
37
|
+
|
38
|
+
# Find a particular account.
|
39
|
+
account = DHL::Ecommerce::Account.find 6369
|
40
|
+
```
|
41
|
+
|
42
|
+
### Locations
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# Find all locations.
|
46
|
+
locations = DHL::Ecommerce::Location.all
|
47
|
+
|
48
|
+
# Find a particular location.
|
49
|
+
location = DHL::Ecommerce::Location.find 6369
|
50
|
+
```
|
51
|
+
|
52
|
+
It's also possible to obtain a list of locations from an account by calling the
|
53
|
+
`locations` method.
|
54
|
+
|
55
|
+
### Labels
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
# Create the consignee's address.
|
59
|
+
consignee_address = DHL::Ecommerce::StandardAddress.new firm: "meowbox Inc.",
|
60
|
+
address_1: "816 PEACE PORTAL DR",
|
61
|
+
address_2: "STE 103",
|
62
|
+
city: "BLAINE",
|
63
|
+
postal_code: "98230",
|
64
|
+
state: "WA",
|
65
|
+
country: "US"
|
66
|
+
|
67
|
+
# Create a single label.
|
68
|
+
label = DHL::Ecommerce::Label.create consignee_address: consignee_address,
|
69
|
+
facility: :auburn,
|
70
|
+
location_id: 6369,
|
71
|
+
product_id: 83,
|
72
|
+
weight: 1
|
73
|
+
```
|
74
|
+
|
75
|
+
The `file` method of any valid label object will return a `StringIO` object
|
76
|
+
containing either the PNG or ZPL representation of the label depending on your
|
77
|
+
configuration.
|
78
|
+
|
79
|
+
It's also possible to create multiple labels at once by passing an array of
|
80
|
+
attributes to the `create` method.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
# Create multiple labels.
|
84
|
+
labels = DHL::Ecommerce::Label.create [ label_attributes_1, label_attributes_2 ]
|
85
|
+
```
|
86
|
+
|
87
|
+
### Manifests
|
88
|
+
|
89
|
+
Unlike other models, the `create` method will always return an array of
|
90
|
+
`Manifest` objects – that's because the DHL e-Commerce API will return a
|
91
|
+
manifest for each location and/or facility.
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# Create manifests
|
95
|
+
manifests = DHL::Ecommerce::Manifest.create labels
|
96
|
+
```
|
97
|
+
|
98
|
+
### Tracking
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
# Find events for a particular label.
|
102
|
+
events = DHL::Ecommerce::Label.find("420000000000000001").events
|
103
|
+
```
|
104
|
+
|
105
|
+
### Other models
|
106
|
+
|
107
|
+
A few supporting models are also available.
|
108
|
+
|
109
|
+
- `Event`
|
110
|
+
- `Imbp`
|
111
|
+
- `Product`
|
112
|
+
- `StandardAddress`
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "builder"
|
2
|
+
require "faraday"
|
3
|
+
require "faraday_middleware"
|
4
|
+
require "faraday_middleware/response/rashify"
|
5
|
+
require "hashie"
|
6
|
+
require "multi_xml"
|
7
|
+
require "rash"
|
8
|
+
|
9
|
+
# Errors
|
10
|
+
require "dhl/ecommerce/errors/base_error"
|
11
|
+
require "dhl/ecommerce/errors/authentication_error"
|
12
|
+
require "dhl/ecommerce/errors/validation_error"
|
13
|
+
|
14
|
+
# Operations
|
15
|
+
require "dhl/ecommerce/operations/find"
|
16
|
+
require "dhl/ecommerce/operations/list"
|
17
|
+
|
18
|
+
# Resources
|
19
|
+
require "dhl/ecommerce/base"
|
20
|
+
require "dhl/ecommerce/account"
|
21
|
+
require "dhl/ecommerce/event"
|
22
|
+
require "dhl/ecommerce/impb"
|
23
|
+
require "dhl/ecommerce/label"
|
24
|
+
require "dhl/ecommerce/location"
|
25
|
+
require "dhl/ecommerce/manifest"
|
26
|
+
require "dhl/ecommerce/product"
|
27
|
+
require "dhl/ecommerce/standard_address"
|
28
|
+
require "dhl/ecommerce/tracked_event"
|
29
|
+
|
30
|
+
# Version
|
31
|
+
require "dhl/ecommerce/version"
|
32
|
+
|
33
|
+
module DHL
|
34
|
+
module Ecommerce
|
35
|
+
@access_token = ENV["DHL_ECOMMERCE_ACCESS_TOKEN"]
|
36
|
+
@client_id = ENV["DHL_ECOMMERCE_CLIENT_ID"]
|
37
|
+
@password = ENV["DHL_ECOMMERCE_PASSWORD"]
|
38
|
+
@username = ENV["DHL_ECOMMERCE_USERNAME"]
|
39
|
+
@label_format = :png
|
40
|
+
|
41
|
+
class << self
|
42
|
+
attr_accessor :client_id, :label_format
|
43
|
+
attr_writer :access_token, :password, :username
|
44
|
+
|
45
|
+
def configure
|
46
|
+
yield self
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.access_token
|
51
|
+
# TODO This needs better error handling.
|
52
|
+
@access_token ||= client.get("https://api.dhlglobalmail.com/v1/auth/access_token", username: @username, password: @password, state: Time.now.to_i).body.response.data[:access_token]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.request(method, url, &block)
|
56
|
+
client.params = {
|
57
|
+
access_token: self.access_token,
|
58
|
+
client_id: client_id
|
59
|
+
}
|
60
|
+
|
61
|
+
response = client.run_request method.downcase.to_sym, url, nil, nil, &block
|
62
|
+
|
63
|
+
puts response.to_yaml
|
64
|
+
|
65
|
+
case response.status
|
66
|
+
when 400
|
67
|
+
case response.body.response.meta.error.error_type
|
68
|
+
when "INVALID_CLIENT_ID", "INVALID_KEY", "INVALID_TOKEN", "INACTIVE_KEY"
|
69
|
+
throw Errors::AuthenticationError.new response.body.response.meta.error.error_message, response
|
70
|
+
when "VALIDATION_ERROR", "INVALID_FACILITY_CODE"
|
71
|
+
throw Errors::ValidationError.new response.body.response.meta.error.error_message, response
|
72
|
+
else
|
73
|
+
throw Errors::BaseError.new response.body.response.meta.error.error_message, response
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
response.body.response.data
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
def self.client
|
82
|
+
@client ||= Faraday.new url: "https://api.dhlglobalmail.com/v1/", headers: { accept: "application/xml", content_type: "application/xml;charset=UTF-8" } do |c|
|
83
|
+
c.response :rashify
|
84
|
+
c.response :xml, :content_type => /\bxml$/
|
85
|
+
c.adapter :net_http
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DHL
|
2
|
+
module Ecommerce
|
3
|
+
class Account < Base
|
4
|
+
include DHL::Ecommerce::Operations::Find
|
5
|
+
include DHL::Ecommerce::Operations::List
|
6
|
+
|
7
|
+
attr_reader :id, :address, :email
|
8
|
+
|
9
|
+
def initialize(attributes = {})
|
10
|
+
super attributes
|
11
|
+
|
12
|
+
unless attributes.empty?
|
13
|
+
@id = attributes[:account].to_i if attributes[:account]
|
14
|
+
@address = StandardAddress.new attributes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def locations
|
19
|
+
response = DHL::Ecommerce.request :get, "https://api.dhlglobalmail.com/v1/#{self.resource_name.downcase}s/#{id}/#{DHL::Ecommerce::Location.resource_name.downcase}s"
|
20
|
+
response[self.resource_name]["#{DHL::Ecommerce::Location.resource_name}s"][DHL::Ecommerce::Location.resource_name] = [response[self.resource_name]["#{DHL::Ecommerce::Location.resource_name}s"][DHL::Ecommerce::Location.resource_name]] unless response[self.resource_name]["#{DHL::Ecommerce::Location.resource_name}s"][DHL::Ecommerce::Location.resource_name].is_a? Array
|
21
|
+
|
22
|
+
response[self.resource_name]["#{DHL::Ecommerce::Location.resource_name}s"].map do |attributes|
|
23
|
+
location = DHL::Ecommerce::Location.new attributes
|
24
|
+
location.instance_variable_set :@account, self
|
25
|
+
location
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module DHL
|
2
|
+
module Ecommerce
|
3
|
+
class Base
|
4
|
+
def initialize(attributes = {})
|
5
|
+
attributes.each do |attribute, value|
|
6
|
+
next if attribute.to_sym == :class
|
7
|
+
|
8
|
+
if respond_to? "#{attribute}="
|
9
|
+
send "#{attribute}=", value
|
10
|
+
elsif respond_to?("#{attribute}")
|
11
|
+
instance_variable_set "@#{attribute}", value
|
12
|
+
end
|
13
|
+
end unless attributes.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def self.resource_name
|
18
|
+
self.name.split("::").last
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DHL
|
2
|
+
module Ecommerce
|
3
|
+
class Event < Base
|
4
|
+
include DHL::Ecommerce::Operations::Find
|
5
|
+
include DHL::Ecommerce::Operations::List
|
6
|
+
|
7
|
+
attr_reader :id, :description
|
8
|
+
|
9
|
+
def initialize(attributes = {})
|
10
|
+
super attributes
|
11
|
+
|
12
|
+
unless attributes.empty?
|
13
|
+
@description.upcase! if @description
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
module DHL
|
2
|
+
module Ecommerce
|
3
|
+
class Label < Base
|
4
|
+
attr_accessor :customer_confirmation_number, :service_endorsement, :reference, :batch, :mail_type, :facility, :expected_ship_date, :weight, :consignee_address, :return_address, :service
|
5
|
+
attr_reader :id, :location_id, :product_id, :events, :service_type, :file, :impb
|
6
|
+
|
7
|
+
FACILITIES = {
|
8
|
+
auburn: "USSEA1",
|
9
|
+
compton: "USLAX1",
|
10
|
+
denver: "USDEN1",
|
11
|
+
edgewood: "USISP1",
|
12
|
+
elkridge: "USBWI1",
|
13
|
+
forest_park: "USATL1",
|
14
|
+
franklin: "USBOS1",
|
15
|
+
grand_prairie: "USDFW1",
|
16
|
+
hebron: "USCVG1",
|
17
|
+
melrose_park: "USORD1",
|
18
|
+
memphis: "USMEM1",
|
19
|
+
orlando: "USMCO1",
|
20
|
+
phoenix: "USPHX1",
|
21
|
+
salt_lake_city: "USSLC1",
|
22
|
+
secaucus: "USEWR1",
|
23
|
+
st_louis: "USSTL1",
|
24
|
+
union_city: "USSFO1"
|
25
|
+
}
|
26
|
+
|
27
|
+
MAIL_TYPES = {
|
28
|
+
bound_printed_matter: 6,
|
29
|
+
irregular_parcel: 2,
|
30
|
+
machinable_parcel: 3,
|
31
|
+
marketing_parcel_gte_6oz: 30,
|
32
|
+
marketing_parcel_lt_6oz: 20,
|
33
|
+
media_mail: 9,
|
34
|
+
parcel_select_machinable: 7,
|
35
|
+
parcel_select_nonmachinable: 8
|
36
|
+
}
|
37
|
+
|
38
|
+
SERVICES = {
|
39
|
+
delivery_confirmation: "DELCON",
|
40
|
+
signature_confirmation: "SIGCON"
|
41
|
+
}
|
42
|
+
|
43
|
+
SERVICE_ENDORSEMENTS = {
|
44
|
+
address_service: 1,
|
45
|
+
change_service: 3,
|
46
|
+
forwarding_service: 2,
|
47
|
+
return_service: 4
|
48
|
+
}
|
49
|
+
|
50
|
+
def location_id=(location_id)
|
51
|
+
@location = nil
|
52
|
+
@location_id = location_id
|
53
|
+
end
|
54
|
+
|
55
|
+
def location
|
56
|
+
@location ||= DHL::Ecommerce::Location.find location_id
|
57
|
+
end
|
58
|
+
|
59
|
+
def location=(location)
|
60
|
+
@location = nil if @location_id != location.id
|
61
|
+
@location_id = location.id
|
62
|
+
end
|
63
|
+
|
64
|
+
def product_id=(product_id)
|
65
|
+
@product = nil
|
66
|
+
@product_id = product_id
|
67
|
+
end
|
68
|
+
|
69
|
+
def product
|
70
|
+
@product ||= DHL::Ecommerce::Product.find product_id
|
71
|
+
end
|
72
|
+
|
73
|
+
def product=(product)
|
74
|
+
@product = nil if @product_id != product.id
|
75
|
+
@product_id = product.id
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.create(attributes)
|
79
|
+
array = attributes.is_a? Array
|
80
|
+
attributes = [attributes] unless array
|
81
|
+
|
82
|
+
labels = self.create_in_batches attributes
|
83
|
+
|
84
|
+
array ? labels : labels.first
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.find(id)
|
88
|
+
attributes = DHL::Ecommerce.request :get, "https://api.dhlglobalmail.com/v1/mailitems/track" do |request|
|
89
|
+
request.params[:number] = id
|
90
|
+
end
|
91
|
+
|
92
|
+
attributes[:mail_items][:mail_item] = attributes[:mail_items][:mail_item].first if attributes[:mail_items][:mail_item].is_a? Array
|
93
|
+
|
94
|
+
new attributes[:mail_items][:mail_item]
|
95
|
+
end
|
96
|
+
|
97
|
+
def initialize(attributes = {})
|
98
|
+
super attributes
|
99
|
+
|
100
|
+
unless attributes.empty?
|
101
|
+
if attributes[:mail]
|
102
|
+
@id = attributes[:mail][:mailIdentifier] if attributes[:mail][:mailIdentifier]
|
103
|
+
@weight = attributes[:mail][:weight] if attributes[:mail][:weight]
|
104
|
+
@product_id = attributes[:mail][:product_id] if attributes[:mail][:product_id]
|
105
|
+
@reference = attributes[:mail][:customer_reference] if attributes[:mail][:customer_reference]
|
106
|
+
@batch = attributes[:mail][:batch_reference] if attributes[:mail][:batch_reference]
|
107
|
+
@impb = attributes[:mail][:intelligent_mail_barcode] if attributes[:mail][:intelligent_mail_barcode]
|
108
|
+
@customer_confirmation_number = attributes[:mail][:customer_confirmation_number] if attributes[:mail][:customer_confirmation_number]
|
109
|
+
|
110
|
+
@services = :delivery_confirmation if attributes[:mail][:delivery_confirmation_flag] == '1'
|
111
|
+
@services = :signature_confirmation if attributes[:mail][:signature_confirmation_flag] == '1'
|
112
|
+
end
|
113
|
+
|
114
|
+
if attributes[:pickup]
|
115
|
+
@location_id = attributes[:pickup][:pickup] if attributes[:pickup][:pickup]
|
116
|
+
end
|
117
|
+
|
118
|
+
if attributes[:recipient]
|
119
|
+
@consignee_address = StandardAddress.new attributes[:recipient]
|
120
|
+
end
|
121
|
+
|
122
|
+
if attributes[:events]
|
123
|
+
@events = []
|
124
|
+
|
125
|
+
attributes[:events][:event] = [attributes[:events][:event]] unless attributes[:events][:event].is_a? Array
|
126
|
+
attributes[:events][:event].each do |event_attributes|
|
127
|
+
event = TrackedEvent.new event_attributes
|
128
|
+
event.instance_variable_set :@event, Event.new(event_attributes)
|
129
|
+
|
130
|
+
@events << event
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def xml
|
139
|
+
xml = Builder::XmlMarkup.new
|
140
|
+
xml.Mpu do
|
141
|
+
xml.PackageId customer_confirmation_number
|
142
|
+
|
143
|
+
xml.PackageRef do
|
144
|
+
xml.PrintFlag customer_confirmation_number.present?
|
145
|
+
# xml.LabelText ""
|
146
|
+
end
|
147
|
+
|
148
|
+
xml.ConsigneeAddress do
|
149
|
+
xml.StandardAddress do
|
150
|
+
xml.Name consignee_address.name
|
151
|
+
xml.Firm consignee_address.firm
|
152
|
+
xml.Address1 consignee_address.address_1
|
153
|
+
xml.Address2 consignee_address.address_2
|
154
|
+
xml.City consignee_address.city
|
155
|
+
xml.State consignee_address.state.to_s.upcase
|
156
|
+
xml.Zip consignee_address.postal_code
|
157
|
+
xml.CountryCode consignee_address.country.to_s.upcase
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
xml.ReturnAddress do
|
162
|
+
xml.StandardAddress do
|
163
|
+
xml.Name return_address.name
|
164
|
+
xml.Firm return_address.firm
|
165
|
+
xml.Address1 return_address.address_1
|
166
|
+
xml.Address2 return_address.address_2
|
167
|
+
xml.City return_address.city
|
168
|
+
xml.State return_address.state.to_s.upcase
|
169
|
+
xml.Zip return_address.postal_code
|
170
|
+
xml.CountryCode return_address.country.to_s.upcase
|
171
|
+
end
|
172
|
+
end if return_address
|
173
|
+
|
174
|
+
xml.OrderedProductCode product_id
|
175
|
+
xml.Service SERVICES.fetch service.downcase.to_sym if service
|
176
|
+
xml.ServiceEndorsement SERVICE_ENDORSEMENTS.fetch service_endorsement.downcase.to_sym if service_endorsement
|
177
|
+
|
178
|
+
# xml.DgCategory ""
|
179
|
+
# xml.ContactPhoneNumber ""
|
180
|
+
|
181
|
+
xml.Weight do
|
182
|
+
xml.Value weight
|
183
|
+
|
184
|
+
# TODO Add support for other units supported by DHL e-Commerce.
|
185
|
+
xml.Unit :lb.to_s.upcase
|
186
|
+
end
|
187
|
+
|
188
|
+
xml.BillingRef1 reference
|
189
|
+
xml.BillingRef2 batch
|
190
|
+
xml.FacilityCode FACILITIES.fetch facility.downcase.to_sym if facility
|
191
|
+
xml.ExpectedShipDate (expected_ship_date || DateTime.now).strftime("%Y%m%d")
|
192
|
+
xml.MailTypeCode MAIL_TYPES.fetch mail_type ? mail_type.downcase.to_sym : :parcel_select_machinable
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.create_in_batches(attributes)
|
197
|
+
attributes.group_by do |value| value[:location_id] end.each.collect do |location_id, location_attributes|
|
198
|
+
case DHL::Ecommerce.label_format
|
199
|
+
when :png, :image
|
200
|
+
url = "https://api.dhlglobalmail.com/v1/#{self.resource_name.downcase}/US/#{location_id}/image"
|
201
|
+
when :zpl
|
202
|
+
url = "https://api.dhlglobalmail.com/v1/#{self.resource_name.downcase}/US/#{location_id}/zpl"
|
203
|
+
end
|
204
|
+
|
205
|
+
location_attributes.each_slice(500).collect do |slice|
|
206
|
+
labels = slice.map do |slice_attributes|
|
207
|
+
new slice_attributes
|
208
|
+
end
|
209
|
+
|
210
|
+
xml = Builder::XmlMarkup.new
|
211
|
+
xml.instruct! :xml, version: "1.1", encoding: "UTF-8"
|
212
|
+
xml.EncodeRequest do
|
213
|
+
xml.CustomerId location_id
|
214
|
+
xml.BatchRef DateTime.now.strftime("%Q")
|
215
|
+
xml.HalfOnError false
|
216
|
+
xml.RejectAllOnError true
|
217
|
+
xml.MpuList do
|
218
|
+
xml << labels.map do |label| label.send :xml end.join
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
response = DHL::Ecommerce.request :post, url do |request|
|
223
|
+
request.body = xml.target!
|
224
|
+
end
|
225
|
+
|
226
|
+
response[:mpu_list][:mpu] = [response[:mpu_list][:mpu]] unless response[:mpu_list][:mpu].is_a? Array
|
227
|
+
|
228
|
+
labels.zip(response[:mpu_list][:mpu]).map do |label, label_response|
|
229
|
+
label.instance_variable_set :@id, label_response[:mail_item_id].to_i if label_response[:mail_item_id]
|
230
|
+
|
231
|
+
case DHL::Ecommerce.label_format
|
232
|
+
when :png, :image
|
233
|
+
label.instance_variable_set :@file, StringIO.new(Base64.decode64(label_response[:label_image])) if label_response[:label_image]
|
234
|
+
when :zpl
|
235
|
+
label.instance_variable_set :@file, StringIO.new(Base64.decode64(label_response[:label_zpl])) if label_response[:label_zpl]
|
236
|
+
end
|
237
|
+
|
238
|
+
if label_response[:label_detail]
|
239
|
+
label.instance_variable_set :@impb, Impb.new(label_response[:label_detail][:impb]) if label_response[:label_detail][:impb]
|
240
|
+
label.instance_variable_set :@service_type, label_response[:label_detail][:service_type_code].to_i if label_response[:label_detail][:service_type_code]
|
241
|
+
end
|
242
|
+
|
243
|
+
label
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end.flatten
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|