dhl-ecommerce 1.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.
- 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
|
+
[](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
|