active_shipping 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -0
- data/README.markdown +8 -37
- data/lib/active_shipping/shipping/carriers.rb +2 -1
- data/lib/active_shipping/shipping/carriers/canada_post.rb +254 -0
- data/lib/active_shipping/shipping/carriers/ups.rb +0 -3
- data/lib/active_shipping/version.rb +1 -1
- data/lib/certs/eParcel.dtd +111 -0
- metadata +6 -4
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
@@ -16,6 +16,7 @@ Active Shipping is currently being used and improved in a production environment
|
|
16
16
|
* [UPS](http://www.ups.com)
|
17
17
|
* [USPS](http://www.usps.com)
|
18
18
|
* [FedEx](http://www.fedex.com)
|
19
|
+
* [Canada Post](http://www.canadapost.ca)
|
19
20
|
* more soon!
|
20
21
|
|
21
22
|
## Prerequisites
|
@@ -43,6 +44,8 @@ Active Shipping includes an init.rb file. This means that Rails will automatical
|
|
43
44
|
|
44
45
|
## Sample Usage
|
45
46
|
|
47
|
+
### Compare rates from different carriers
|
48
|
+
|
46
49
|
require 'active_shipping'
|
47
50
|
include ActiveMerchant::Shipping
|
48
51
|
|
@@ -91,21 +94,10 @@ Active Shipping includes an init.rb file. This means that Rails will automatical
|
|
91
94
|
# ["USPS Global Express Guaranteed Non-Document Rectangular", 9400],
|
92
95
|
# ["USPS Global Express Guaranteed", 9400]]
|
93
96
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
# => [["FedEx Ground", 977],
|
99
|
-
# ["FedEx Ground Home Delivery", 1388],
|
100
|
-
# ["FedEx Express Saver", 2477],
|
101
|
-
# ["FedEx 2 Day", 2718],
|
102
|
-
# ["FedEx Standard Overnight", 4978],
|
103
|
-
# ["FedEx Priority Overnight", 8636],
|
104
|
-
# ["FedEx First Overnight", 12306]]
|
105
|
-
|
106
|
-
# FedEx Tracking
|
107
|
-
fdx = FedEx.new(:login => '999999999', :password => '7777777')
|
108
|
-
tracking_info = fdx.find_tracking_info('tracking number here', :carrier_code => 'fedex_ground') # Ground package
|
97
|
+
### Track a FedEx package
|
98
|
+
|
99
|
+
fedex = FedEx.new(:login => '999999999', :password => '7777777')
|
100
|
+
tracking_info = fedex.find_tracking_info('tracking-number', :carrier_code => 'fedex_ground') # Ground package
|
109
101
|
|
110
102
|
tracking_info.shipment_events.each do |event|
|
111
103
|
puts "#{event.name} at #{event.location.city}, #{event.location.state} on #{event.time}. #{event.message}"
|
@@ -117,34 +109,12 @@ Active Shipping includes an init.rb file. This means that Rails will automatical
|
|
117
109
|
# Arrived at FedEx sort facility at KNOXVILLE, TN on Fri Oct 24 02:45:00 UTC 2008.
|
118
110
|
# Scanned at FedEx sort facility at KNOXVILLE, TN on Fri Oct 24 05:56:00 UTC 2008.
|
119
111
|
# Delivered at Knoxville, TN on Fri Oct 24 16:45:00 UTC 2008. Signed for by: T.BAKER
|
120
|
-
|
121
|
-
tracking_info = fdx.find_tracking_info('tracking number here', :carrier_code => 'fedex_express') # Express package
|
122
|
-
|
123
|
-
tracking_info.shipment_events.each do |event|
|
124
|
-
puts "#{event.name} at #{event.location.city}, #{event.location.state} on #{event.time}. #{event.message}"
|
125
|
-
end
|
126
|
-
# => Picked up by FedEx at NASHVILLE, TN on Wed Dec 03 16:46:00 UTC 2008.
|
127
|
-
# Package status at MISSISSAUGA, ON on Wed Dec 03 18:00:00 UTC 2008.
|
128
|
-
# Left FedEx Origin Location at NASHVILLE, TN on Wed Dec 03 20:27:00 UTC 2008.
|
129
|
-
# Arrived at FedEx Ramp at NASHVILLE, TN on Wed Dec 03 20:43:00 UTC 2008.
|
130
|
-
# Left FedEx Ramp at NASHVILLE, TN on Wed Dec 03 22:30:00 UTC 2008.
|
131
|
-
# Arrived at Sort Facility at INDIANAPOLIS, IN on Thu Dec 04 00:31:00 UTC 2008.
|
132
|
-
# Left FedEx Sort Facility at INDIANAPOLIS, IN on Thu Dec 04 01:14:00 UTC 2008.
|
133
|
-
# Left FedEx Sort Facility at INDIANAPOLIS, IN on Thu Dec 04 04:48:00 UTC 2008.
|
134
|
-
# Arrived at FedEx Ramp at MISSISSAUGA, ON on Thu Dec 04 06:26:00 UTC 2008.
|
135
|
-
# Package status at MISSISSAUGA, ON on Thu Dec 04 07:03:00 UTC 2008.
|
136
|
-
# Left FedEx Ramp at MISSISSAUGA, ON on Thu Dec 04 07:37:00 UTC 2008.
|
137
|
-
# Arrived at FedEx Destination Location at TORONTO, ON on Thu Dec 04 08:42:00 UTC 2008.
|
138
|
-
# On FedEx vehicle for delivery at TORONTO, ON on Thu Dec 04 09:04:00 UTC 2008.
|
139
|
-
# Delivered to Non-FedEx clearance broker at TORONTO, ON on Thu Dec 04 10:15:00 UTC 2008.
|
140
112
|
|
141
113
|
## TODO
|
142
114
|
|
143
115
|
* proper documentation
|
144
|
-
* proper offline testing for carriers in addition to the remote tests
|
145
116
|
* carrier code template generator
|
146
117
|
* more carriers
|
147
|
-
* integrate with ActiveMerchant
|
148
118
|
* support more features for existing carriers
|
149
119
|
* bin-packing algorithm (preferably implemented in ruby)
|
150
120
|
* order tracking
|
@@ -164,6 +134,7 @@ The nicest way to submit changes would be to set up a GitHub account and fork th
|
|
164
134
|
* Tobias Luetke (<http://blog.leetsoft.com>)
|
165
135
|
* Cody Fauser (<http://codyfauser.com>)
|
166
136
|
* Jimmy Baker (<http://jimmyville.com/>)
|
137
|
+
* William Lang (<http://williamlang.net/>)
|
167
138
|
|
168
139
|
## Legal Mumbo Jumbo
|
169
140
|
|
@@ -4,13 +4,14 @@ require 'active_shipping/shipping/carriers/usps'
|
|
4
4
|
require 'active_shipping/shipping/carriers/fedex'
|
5
5
|
require 'active_shipping/shipping/carriers/shipwire'
|
6
6
|
require 'active_shipping/shipping/carriers/kunaki'
|
7
|
+
require 'active_shipping/shipping/carriers/canada_post'
|
7
8
|
|
8
9
|
module ActiveMerchant
|
9
10
|
module Shipping
|
10
11
|
module Carriers
|
11
12
|
class <<self
|
12
13
|
def all
|
13
|
-
[BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki]
|
14
|
+
[BogusCarrier, UPS, USPS, FedEx, Shipwire, Kunaki, CanadaPost]
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module ActiveMerchant
|
4
|
+
module Shipping
|
5
|
+
|
6
|
+
class CanadaPost < Carrier
|
7
|
+
|
8
|
+
# NOTE!
|
9
|
+
# A Merchant CPC Id must be assigned to you by Canada Post
|
10
|
+
# CPC_DEMO_XML is just a public domain account for testing
|
11
|
+
|
12
|
+
class CanadaPostRateResponse < RateResponse
|
13
|
+
|
14
|
+
attr_reader :boxes, :postal_outlets
|
15
|
+
|
16
|
+
def initialize(success, message, params = {}, options = {})
|
17
|
+
@boxes = options[:boxes]
|
18
|
+
@postal_outlets = options[:postal_outlets]
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
cattr_reader :name, :name_french
|
25
|
+
@@name = "Canada Post"
|
26
|
+
@@name_french = "Postes Canada"
|
27
|
+
|
28
|
+
Box = Struct.new(:name, :weight, :expediter_weight, :length, :width, :height, :packedItems)
|
29
|
+
PackedItem = Struct.new(:quantity, :description)
|
30
|
+
PostalOutlet = Struct.new(:sequence_no, :distance, :name, :business_name, :postal_address, :business_hours)
|
31
|
+
|
32
|
+
DEFAULT_TURN_AROUND_TIME = 24
|
33
|
+
URL = "http://sellonline.canadapost.ca:30000"
|
34
|
+
DOCTYPE = '<!DOCTYPE eparcel SYSTEM "http://sellonline.canadapost.ca/DevelopersResources/protocolV3/eParcel.dtd">'
|
35
|
+
|
36
|
+
RESPONSE_CODES = {
|
37
|
+
'1' => "All calculation was done",
|
38
|
+
'2' => "Default shipping rates are returned due to a problem during the processing of the request.",
|
39
|
+
'-2' => "Missing argument when calling module",
|
40
|
+
'-5' => "No Item to ship",
|
41
|
+
'-6' => "Illegal Item weight",
|
42
|
+
'-7' => "Illegal item dimension",
|
43
|
+
'-12' => "Can't open IM config file",
|
44
|
+
'-13' => "Can't create log files",
|
45
|
+
'-15' => "Invalid config file format",
|
46
|
+
'-102' => "Invalid socket connection",
|
47
|
+
'-106' => "Can't connect to server",
|
48
|
+
'-1000' => "Unknow request type sent by client",
|
49
|
+
'-1002' => "MAS Timed out",
|
50
|
+
'-1004' => "Socket communication break",
|
51
|
+
'-1005' => "Did not receive required data on socket.",
|
52
|
+
'-2000' => "Unable to estabish socket connection with RSSS",
|
53
|
+
'-2001' => "Merchant Id not found on server",
|
54
|
+
'-2002' => "One or more parameter was not sent by the IM to the MAS",
|
55
|
+
'-2003' => "Did not receive required data on socket.",
|
56
|
+
'-2004' => "The request contains to many items to process it.",
|
57
|
+
'-2005' => "The request received on socket is larger than the maximum allowed.",
|
58
|
+
'-3000' => "Origin Postal Code is illegal",
|
59
|
+
'-3001' => "Destination Postal Code/State Name/ Country is illegal",
|
60
|
+
'-3002' => "Parcel too large to be shipped with CPC",
|
61
|
+
'-3003' => "Parcel too small to be shipped with CPC",
|
62
|
+
'-3004' => "Parcel too heavy to be shipped with CPC",
|
63
|
+
'-3005' => "Internal error code returned by the rating DLL",
|
64
|
+
'-3006' => "The pick up time format is invalid or not defined.",
|
65
|
+
'-4000' => "Volumetric internal error",
|
66
|
+
'-4001' => "Volumetric time out calculation error.",
|
67
|
+
'-4002' => "No bins provided to the volumetric engine.",
|
68
|
+
'-4003' => "No items provided to the volumetric engine.",
|
69
|
+
'-4004' => "Item is too large to be packed",
|
70
|
+
'-4005' => "Number of item more than maximum allowed",
|
71
|
+
'-5000' => "XML Parsing error",
|
72
|
+
'-5001' => "XML Tag not found",
|
73
|
+
'-5002' => "Node Value Number format error",
|
74
|
+
'-5003' => "Node value is empty",
|
75
|
+
'-5004' => "Unable to create/parse XML Document",
|
76
|
+
'-6000' => "Unable to open the database",
|
77
|
+
'-6001' => "Unable to read from the database",
|
78
|
+
'-6002' => "Unable to write to the database",
|
79
|
+
'-50000' => "Internal problem - Please contact Sell Online Help Desk"
|
80
|
+
}
|
81
|
+
|
82
|
+
def requirements
|
83
|
+
[:login]
|
84
|
+
end
|
85
|
+
|
86
|
+
def find_rates(origin, destination, line_items = [], options = {})
|
87
|
+
rate_request = build_rate_request(origin, destination, line_items, options)
|
88
|
+
commit(rate_request, origin, destination, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
def maximum_weight
|
92
|
+
Mass.new(30, :kilograms)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.default_location
|
96
|
+
{
|
97
|
+
:country => 'CA',
|
98
|
+
:province => 'ON',
|
99
|
+
:city => 'Ottawa',
|
100
|
+
:address1 => '61A York St',
|
101
|
+
:postal_code => 'K1N5T2'
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
def commit(request, origin, destination, options = {})
|
108
|
+
response = parse_rate_response(ssl_post(URL, request), origin, destination, options)
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def build_rate_request(origin, destination, line_items = [], options = {})
|
114
|
+
line_items = [line_items] if !line_items.is_a?(Array)
|
115
|
+
origin = origin.is_a?(Location) ? origin : Location.new(origin)
|
116
|
+
destination = destination.is_a?(Location) ? destination : Location.new(destination)
|
117
|
+
|
118
|
+
xml_request = XmlNode.new('eparcel') do |root_node|
|
119
|
+
root_node << XmlNode.new('language', @options[:french] ? 'fr' : 'en')
|
120
|
+
root_node << XmlNode.new('ratesAndServicesRequest') do |request|
|
121
|
+
|
122
|
+
request << XmlNode.new('merchantCPCID', @options[:login])
|
123
|
+
request << XmlNode.new('fromPostalCode', origin.postal_code)
|
124
|
+
request << XmlNode.new('turnAroundTime', options[:turn_around_time] ? options[:turn_around_time] : DEFAULT_TURN_AROUND_TIME)
|
125
|
+
request << XmlNode.new('itemsPrice', line_items.sum(&:value))
|
126
|
+
|
127
|
+
#line items
|
128
|
+
request << build_line_items(line_items)
|
129
|
+
|
130
|
+
#delivery info
|
131
|
+
#NOTE: These tags MUST be after line items
|
132
|
+
request << XmlNode.new('city', destination.city)
|
133
|
+
request << XmlNode.new('provOrState', destination.province)
|
134
|
+
request << XmlNode.new('country', destination.country)
|
135
|
+
request << XmlNode.new('postalCode', destination.postal_code)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
DOCTYPE + xml_request.to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
def parse_rate_response(response, origin, destination, options = {})
|
143
|
+
xml = REXML::Document.new(response)
|
144
|
+
success = response_success?(xml)
|
145
|
+
message = response_message(xml)
|
146
|
+
|
147
|
+
rate_estimates = []
|
148
|
+
boxes = []
|
149
|
+
if success
|
150
|
+
xml.elements.each('eparcel/ratesAndServicesResponse/product') do |product|
|
151
|
+
service_name = (@options[:french] ? @@name_french : @@name) + product.get_text('name').to_s
|
152
|
+
service_code = product.attribute('id').to_s
|
153
|
+
delivery_date = date_for(product.get_text('deliveryDate').to_s)
|
154
|
+
|
155
|
+
rate_estimates << RateEstimate.new(origin, destination, @@name, service_name,
|
156
|
+
:service_code => service_code,
|
157
|
+
:total_price => product.get_text('rate').to_s,
|
158
|
+
:delivery_date => delivery_date,
|
159
|
+
:currency => 'CAD'
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
boxes = xml.elements.collect('eparcel/ratesAndServicesResponse/packing/box') do |box|
|
164
|
+
b = Box.new
|
165
|
+
b.packedItems = []
|
166
|
+
b.name = box.get_text('name').to_s
|
167
|
+
b.weight = box.get_text('weight').to_s.to_f
|
168
|
+
b.expediter_weight = box.get_text('expediterWeight').to_s.to_f
|
169
|
+
b.length = box.get_text('length').to_s.to_f
|
170
|
+
b.width = box.get_text('width').to_s.to_f
|
171
|
+
b.height = box.get_text('height').to_s.to_f
|
172
|
+
b.packedItems = box.elements.collect('packedItem') do |item|
|
173
|
+
p = PackedItem.new
|
174
|
+
p.quantity = item.get_text('quantity').to_s.to_i
|
175
|
+
p.description = item.get_text('description').to_s
|
176
|
+
p
|
177
|
+
end
|
178
|
+
b
|
179
|
+
end
|
180
|
+
|
181
|
+
postal_outlets = xml.elements.collect('eparcel/ratesAndServicesResponse/nearestPostalOutlet') do |outlet|
|
182
|
+
postal_outlet = PostalOutlet.new
|
183
|
+
postal_outlet.sequence_no = outlet.get_text('postalOutletSequenceNo').to_s
|
184
|
+
postal_outlet.distance = outlet.get_text('distance').to_s
|
185
|
+
postal_outlet.name = outlet.get_text('outletName').to_s
|
186
|
+
postal_outlet.business_name = outlet.get_text('businessName').to_s
|
187
|
+
|
188
|
+
postal_outlet.postal_address = Location.new({
|
189
|
+
:address1 => outlet.get_text('postalAddress/addressLine').to_s,
|
190
|
+
:postal_code => outlet.get_text('postalAddress/postal_code').to_s,
|
191
|
+
:city => outlet.get_text('postalAddress/municipality').to_s,
|
192
|
+
:province => outlet.get_text('postalAddress/province').to_s,
|
193
|
+
:country => 'Canada',
|
194
|
+
:phone_number => outlet.get_text('phoneNumber').to_s
|
195
|
+
})
|
196
|
+
|
197
|
+
postal_outlet.business_hours = outlet.elements.collect('businessHours') do |hour|
|
198
|
+
{ :day_of_week => hour.get_text('dayOfWeek').to_s, :time => hour.get_text('time').to_s }
|
199
|
+
end
|
200
|
+
|
201
|
+
postal_outlet
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
CanadaPostRateResponse.new(success, message, Hash.from_xml(response), :rates => rate_estimates, :xml => response, :boxes => boxes, :postal_outlets => postal_outlets)
|
206
|
+
end
|
207
|
+
|
208
|
+
def date_for(string)
|
209
|
+
return if !string
|
210
|
+
return Time.parse(string)
|
211
|
+
end
|
212
|
+
|
213
|
+
def response_success?(xml)
|
214
|
+
value = xml.get_text('eparcel/ratesAndServicesResponse/statusCode').to_s
|
215
|
+
value == '1' || value == '2'
|
216
|
+
end
|
217
|
+
|
218
|
+
def response_message(xml)
|
219
|
+
xml.get_text('eparcel/ratesAndServicesResponse/statusMessage').to_s
|
220
|
+
end
|
221
|
+
|
222
|
+
# <!-- List of items in the shopping -->
|
223
|
+
# <!-- cart -->
|
224
|
+
# <!-- Each item is defined by : -->
|
225
|
+
# <!-- - quantity (mandatory) -->
|
226
|
+
# <!-- - size (mandatory) -->
|
227
|
+
# <!-- - weight (mandatory) -->
|
228
|
+
# <!-- - description (mandatory) -->
|
229
|
+
# <!-- - ready to ship (optional) -->
|
230
|
+
|
231
|
+
def build_line_items(line_items)
|
232
|
+
xml_line_items = XmlNode.new('lineItems') do |line_items_node|
|
233
|
+
|
234
|
+
line_items.each do |line_item|
|
235
|
+
|
236
|
+
line_items_node << XmlNode.new('item') do |item|
|
237
|
+
item << XmlNode.new('quantity', 1)
|
238
|
+
item << XmlNode.new('weight', line_item.kilograms)
|
239
|
+
item << XmlNode.new('length', line_item.cm(:length).to_s)
|
240
|
+
item << XmlNode.new('width', line_item.cm(:width).to_s)
|
241
|
+
item << XmlNode.new('height', line_item.cm(:height).to_s)
|
242
|
+
item << XmlNode.new('description', line_item.options[:description] || ' ')
|
243
|
+
item << XmlNode.new('readyToShip', line_item.options[:ready_to_ship] || nil)
|
244
|
+
|
245
|
+
# By setting the 'readyToShip' tag to true, Sell Online will not pack this item in the boxes defined in the merchant profile.
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
xml_line_items
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -175,9 +175,6 @@ module ActiveMerchant
|
|
175
175
|
# * Shipment/DocumentsOnly element
|
176
176
|
|
177
177
|
packages.each do |package|
|
178
|
-
debugger if package.nil?
|
179
|
-
|
180
|
-
|
181
178
|
imperial = ['US','LR','MM'].include?(origin.country_code(:alpha2))
|
182
179
|
|
183
180
|
shipment << XmlNode.new("Package") do |package_node|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
<!-- EVERY REQUEST CONTAIN THE eparcel TAG -->
|
2
|
+
<!ELEMENT eparcel (language?,
|
3
|
+
( ratesAndServicesRequest |
|
4
|
+
ratesAndServicesResponse |
|
5
|
+
error
|
6
|
+
)+)>
|
7
|
+
|
8
|
+
<!ELEMENT language (#PCDATA)>
|
9
|
+
<!ELEMENT comment (#PCDATA)>
|
10
|
+
|
11
|
+
|
12
|
+
<!-- Standard request to ask for rates and services -->
|
13
|
+
<!ELEMENT ratesAndServicesRequest ( merchantCPCID,
|
14
|
+
fromPostalCode?,
|
15
|
+
turnAroundTime?,
|
16
|
+
itemsPrice?,
|
17
|
+
lineItems,
|
18
|
+
city?,
|
19
|
+
provOrState,
|
20
|
+
country,
|
21
|
+
postalCode)>
|
22
|
+
<!ELEMENT merchantID (#PCDATA)>
|
23
|
+
<!ELEMENT fromPostalCode (#PCDATA)>
|
24
|
+
<!ELEMENT turnAroundTime (#PCDATA)>
|
25
|
+
<!ELEMENT itemsPrice (#PCDATA)>
|
26
|
+
<!ELEMENT merchantCPCID (#PCDATA)>
|
27
|
+
<!ELEMENT lineItems (item)+>
|
28
|
+
<!ELEMENT item (quantity, weight, length, width, height, description, imageURL?, readyToShip)>
|
29
|
+
<!ELEMENT quantity (#PCDATA)>
|
30
|
+
<!ELEMENT weight (#PCDATA)>
|
31
|
+
<!ELEMENT length (#PCDATA)>
|
32
|
+
<!ELEMENT width (#PCDATA)>
|
33
|
+
<!ELEMENT height (#PCDATA)>
|
34
|
+
<!ELEMENT description (#PCDATA)>
|
35
|
+
<!ELEMENT imageURL (#PCDATA)>
|
36
|
+
<!ELEMENT readyToShip (#PCDATA)>
|
37
|
+
<!ELEMENT city (#PCDATA)>
|
38
|
+
<!ELEMENT provOrState (#PCDATA)>
|
39
|
+
<!ELEMENT country (#PCDATA)>
|
40
|
+
<!ELEMENT postalCode (#PCDATA)>
|
41
|
+
|
42
|
+
<!-- Standard response for request for rates and services -->
|
43
|
+
<!ELEMENT ratesAndServicesResponse (statusCode,
|
44
|
+
statusMessage+,
|
45
|
+
requestID,
|
46
|
+
handling,
|
47
|
+
language,
|
48
|
+
product+,
|
49
|
+
packing*,
|
50
|
+
emptySpace*,
|
51
|
+
shippingOptions,
|
52
|
+
comment,
|
53
|
+
nearestPostalOutlet*)>
|
54
|
+
|
55
|
+
<!ELEMENT statusCode (#PCDATA)>
|
56
|
+
<!ELEMENT statusMessage (#PCDATA)>
|
57
|
+
<!ELEMENT requestID (#PCDATA)>
|
58
|
+
<!ELEMENT handling (#PCDATA)>
|
59
|
+
|
60
|
+
<!ELEMENT product (name, rate, shippingDate, deliveryDate, deliveryDayOfWeek, nextDayAM?, packingID)>
|
61
|
+
<!ATTLIST product id CDATA #REQUIRED>
|
62
|
+
<!ATTLIST product sequence CDATA #REQUIRED>
|
63
|
+
<!ELEMENT name (#PCDATA)>
|
64
|
+
<!ELEMENT rate (#PCDATA)>
|
65
|
+
<!ELEMENT shippingDate (#PCDATA)>
|
66
|
+
<!ELEMENT deliveryDate (#PCDATA)>
|
67
|
+
<!ELEMENT deliveryDayOfWeek (#PCDATA)>
|
68
|
+
<!ELEMENT nextDayAM (#PCDATA)>
|
69
|
+
<!ELEMENT packingID (#PCDATA)>
|
70
|
+
|
71
|
+
<!ELEMENT packing (packingID, box+)>
|
72
|
+
<!ELEMENT box (name, weight, expediterWeight, length, width, height, packedItem+)>
|
73
|
+
<!ELEMENT expediterWeight (#PCDATA)>
|
74
|
+
<!ELEMENT packedItem (quantity, description)>
|
75
|
+
|
76
|
+
<!ELEMENT emptySpace (length, width, height, weight)>
|
77
|
+
|
78
|
+
<!ELEMENT shippingOptions (insurance, deliveryConfirmation, signature)>
|
79
|
+
<!ELEMENT insurance (#PCDATA)>
|
80
|
+
<!ELEMENT deliveryConfirmation (#PCDATA)>
|
81
|
+
<!ELEMENT signature (#PCDATA)>
|
82
|
+
|
83
|
+
|
84
|
+
<!-- ********************************************************* -->
|
85
|
+
<!-- * 'nearestPostalOutlet' is optional and is returned * -->
|
86
|
+
<!-- * only if the merchant profile has this option enabled * -->
|
87
|
+
<!-- ********************************************************* -->
|
88
|
+
<!ELEMENT nearestPostalOutlet (postalOutletSequenceNo,
|
89
|
+
distance,
|
90
|
+
outletName,
|
91
|
+
businessName ,
|
92
|
+
postalAddress,
|
93
|
+
phoneNumber,
|
94
|
+
businessHours+)>
|
95
|
+
<!ELEMENT postalOutletSequenceNo (#PCDATA)>
|
96
|
+
<!ELEMENT distance (#PCDATA)>
|
97
|
+
<!ELEMENT outletName (#PCDATA)>
|
98
|
+
<!ELEMENT businessName (#PCDATA)>
|
99
|
+
<!ELEMENT postalAddress (addressLine+, postalCode , municipality)>
|
100
|
+
<!ELEMENT addressLine (#PCDATA)>
|
101
|
+
<!ELEMENT municipality (#PCDATA)>
|
102
|
+
<!ELEMENT phoneNumber (#PCDATA)>
|
103
|
+
<!ELEMENT businessHours (dayId, dayOfWeek, time)>
|
104
|
+
<!ELEMENT dayId (#PCDATA)>
|
105
|
+
<!ELEMENT dayOfWeek (#PCDATA)>
|
106
|
+
<!ELEMENT time (#PCDATA)>
|
107
|
+
|
108
|
+
|
109
|
+
<!-- Standard error format returned -->
|
110
|
+
<!ELEMENT error (statusCode,statusMessage*)>
|
111
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 61
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 3
|
10
|
+
version: 0.9.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James MacAulay
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2010-
|
21
|
+
date: 2010-09-21 00:00:00 -04:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/active_shipping/shipping/base.rb
|
74
74
|
- lib/active_shipping/shipping/carrier.rb
|
75
75
|
- lib/active_shipping/shipping/carriers/bogus_carrier.rb
|
76
|
+
- lib/active_shipping/shipping/carriers/canada_post.rb
|
76
77
|
- lib/active_shipping/shipping/carriers/fedex.rb
|
77
78
|
- lib/active_shipping/shipping/carriers/kunaki.rb
|
78
79
|
- lib/active_shipping/shipping/carriers/shipwire.rb
|
@@ -89,6 +90,7 @@ files:
|
|
89
90
|
- lib/active_shipping/version.rb
|
90
91
|
- lib/active_shipping.rb
|
91
92
|
- lib/certs/cacert.pem
|
93
|
+
- lib/certs/eParcel.dtd
|
92
94
|
- lib/vendor/quantified/init.rb
|
93
95
|
- lib/vendor/quantified/lib/quantified/attribute.rb
|
94
96
|
- lib/vendor/quantified/lib/quantified/length.rb
|