active_shipping 0.9.2 → 0.9.3

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,4 @@
1
+ * Add carrier CanadaPost [william]
1
2
  * Update FedEx rates and added ability to auto-generate rate name from code that gets returned by FedEx [dennis]
2
3
  * Assume test_helper is in load path when running tests [cody]
3
4
  * Add support Kunaki rating service [cody]
@@ -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
- # FedEx
95
- fdx = FedEx.new(:login => 'Your 9-digit FedEx Account #', :password => 'Your Meter Number')
96
- response = fdx.find_rates(origin, destination, packages, :test => true)
97
- response.rates.sort_by(&:price).collect {|rate| [rate.service_name, rate.price]}
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|
@@ -1,3 +1,3 @@
1
1
  module ActiveShipping
2
- VERSION = "0.9.2"
2
+ VERSION = "0.9.3"
3
3
  end
@@ -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: 63
4
+ hash: 61
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 2
10
- version: 0.9.2
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-08-06 00:00:00 -04:00
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