fedex 3.6.1 → 3.8.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.
@@ -32,8 +32,17 @@ module Fedex
32
32
  if success?(response)
33
33
  options = response[:track_reply][:track_details]
34
34
 
35
- [options].flatten.map do |details|
36
- Fedex::TrackingInformation.new(details)
35
+ if response[:track_reply][:duplicate_waybill].downcase == 'true'
36
+ shipments = []
37
+ [options].flatten.map do |details|
38
+ options = {:tracking_number => @package_id, :uuid => details[:tracking_number_unique_identifier]}
39
+ shipments << Request::TrackingInformation.new(@credentials, options).process_request
40
+ end
41
+ shipments.flatten
42
+ else
43
+ [options].flatten.map do |details|
44
+ Fedex::TrackingInformation.new(details)
45
+ end
37
46
  end
38
47
  else
39
48
  error_message = if response[:track_reply]
@@ -4,6 +4,11 @@ require 'fedex/request/rate'
4
4
  require 'fedex/request/tracking_information'
5
5
  require 'fedex/request/address'
6
6
  require 'fedex/request/document'
7
+ require 'fedex/request/delete'
8
+ require 'fedex/request/ground_close'
9
+ require 'fedex/request/pickup'
10
+ require 'fedex/request/pickup_availability'
11
+ require 'fedex/request/service_availability'
7
12
 
8
13
  module Fedex
9
14
  class Shipment
@@ -23,7 +28,7 @@ module Fedex
23
28
 
24
29
  # @param [Hash] shipper, A hash containing the shipper information
25
30
  # @param [Hash] recipient, A hash containing the recipient information
26
- # @param [Array] packages, An arrary including a hash for each package being shipped
31
+ # @param [Array] packages, An array including a hash for each package being shipped
27
32
  # @param [String] service_type, A valid fedex service type, to view a complete list of services Fedex::Shipment::SERVICE_TYPES
28
33
  # @param [String] filename, A location where the label will be saved
29
34
  # @param [Hash] label_specification, A hash containing the label printer settings
@@ -33,7 +38,7 @@ module Fedex
33
38
 
34
39
  # @param [Hash] shipper, A hash containing the shipper information
35
40
  # @param [Hash] recipient, A hash containing the recipient information
36
- # @param [Array] packages, An arrary including a hash for each package being shipped
41
+ # @param [Array] packages, An array including a hash for each package being shipped
37
42
  # @param [String] service_type, A valid fedex service type, to view a complete list of services Fedex::Shipment::SERVICE_TYPES
38
43
  def rate(options = {})
39
44
  Request::Rate.new(@credentials, options).process_request
@@ -46,12 +51,21 @@ module Fedex
46
51
 
47
52
  # @param [Hash] shipper, A hash containing the shipper information
48
53
  # @param [Hash] recipient, A hash containing the recipient information
49
- # @param [Array] packages, An arrary including a hash for each package being shipped
54
+ # @param [Array] packages, An array including a hash for each package being shipped
50
55
  # @param [String] service_type, A valid fedex service type, to view a complete list of services Fedex::Shipment::SERVICE_TYPES
51
56
  def ship(options = {})
52
57
  Request::Shipment.new(@credentials, options).process_request
53
58
  end
54
59
 
60
+ # @param [String] carrier_code, A valid fedex carrier code, to view a complete list of carrier codes Fedex::Shipment::CARRIER_CODES
61
+ # @param [Hash] packages, A hash containing the number of packages and their total weight
62
+ # @param [DateTime] ready_timestamp, A timestamp that indicates what day and time the package will be available for pickup
63
+ # @param [Time] close_time, The latest time that the business will be open to accept a pickup
64
+ # @param [Hash] pickup_location, A hash containing the pickup location information
65
+ def pickup(options = {})
66
+ Request::Pickup.new(@credentials, options).process_request
67
+ end
68
+
55
69
  # @param [Hash] package_id, A string with the requested tracking number
56
70
  # @param [Hash] package_type, A string identifitying the type of tracking number used. Full list Fedex::Track::PACKAGE_IDENTIFIER_TYPES
57
71
  def track(options = {})
@@ -60,14 +74,42 @@ module Fedex
60
74
 
61
75
  # @param [Hash] shipper, A hash containing the shipper information
62
76
  # @param [Hash] recipient, A hash containing the recipient information
63
- # @param [Array] packages, An arrary including a hash for each package being shipped
77
+ # @param [Array] packages, An array including a hash for each package being shipped
64
78
  # @param [String] service_type, A valid fedex service type, to view a complete list of services Fedex::Shipment::SERVICE_TYPES
65
79
  # @param [Hash] customs_clearance, A hash containing customs clearance specification
66
80
  # @param [Hash] shipping_document, A hash containing shipping document specification
67
- # @param [Array] filenames, A locations where the label and shipment documents will be saved
81
+ # @param [Array] filenames, A location where the label and shipment documents will be saved
68
82
  def document(options = {})
69
83
  Request::Document.new(@credentials, options).process_request
70
84
  end
71
85
 
86
+ # @param [Hash] package_id, A string with the tracking number to delete
87
+ def delete(options = {})
88
+ Request::Delete.new(@credentials, options).process_request
89
+ end
90
+
91
+ # @param [Date] up_to_time, A time up to which shipments are to be closed
92
+ # @param [String] filename, A location where the manifest (text file) will be saved
93
+ def ground_close(options = {})
94
+ Request::GroundClose.new(@credentials, options).process_request
95
+ end
96
+ # @param [String] country_code, A string containing country code
97
+ # @param [String] state_code, A string containing state code
98
+ # @param [String] postal_code, A string containing postal code
99
+ # @param [String] carrier_code, A string containing carrier code
100
+ # @param [String] request_type, A string with request type
101
+ # @param [String] dispatch_date, A string with dispatch date in YYYY-MM-DD format
102
+ def pickup_availability(options = {})
103
+ Request::PickupAvailability.new(@credentials, options).process_request
104
+ end
105
+
106
+ # param [Hash] origin, A hash containing origin information
107
+ # param [Hash] destination, A hash containing destination information
108
+ # param [date] ship_date, A string containing ship date in YYYY-MM-DD format
109
+ # param [String] carrier_code, A string containing carrier code
110
+ def service_availability(options = {})
111
+ Request::ServiceAvailability.new(@credentials, options).process_request
112
+ end
113
+
72
114
  end
73
115
  end
@@ -29,7 +29,7 @@ module Fedex
29
29
  }
30
30
 
31
31
  attr_reader :tracking_number, :signature_name, :service_type, :status,
32
- :delivery_at, :events, :unique_tracking_number, :details
32
+ :delivery_at, :events, :unique_tracking_number, :details, :other_identifiers
33
33
 
34
34
  def initialize(details = {})
35
35
  @details = details
@@ -39,6 +39,7 @@ module Fedex
39
39
  @signature_name = details[:delivery_signature_name]
40
40
  @service_type = details[:service_type]
41
41
  @status = details[:status_description]
42
+ @other_identifiers = details[:other_identifiers]
42
43
 
43
44
  if details.has_key?(:actual_delivery_timestamp)
44
45
  @delivery_at = Time.parse(details[:actual_delivery_timestamp])
@@ -1,13 +1,15 @@
1
1
  module Fedex
2
2
  class TrackingInformation
3
3
  class Event
4
- attr_reader :description, :type, :occured_at, :city, :state, :postal_code,
4
+ attr_reader :description, :type, :occurred_at, :city, :state, :postal_code,
5
5
  :country, :residential, :exception_code, :exception_description
6
6
 
7
+ alias_method :occured_at, :occurred_at
8
+
7
9
  def initialize(details = {})
8
10
  @description = details[:event_description]
9
11
  @type = details[:event_type]
10
- @occured_at = Time.parse(details[:timestamp])
12
+ @occurred_at = Time.parse(details[:timestamp])
11
13
  @city = details[:address][:city]
12
14
  @state = details[:address][:state_or_province_code]
13
15
  @postal_code = details[:address][:postal_code]
@@ -16,6 +18,7 @@ module Fedex
16
18
  @exception_code = details[:status_exception_code]
17
19
  @exception_description = details[:status_exception_description]
18
20
  end
21
+
19
22
  end
20
23
  end
21
24
  end
data/lib/fedex/version.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Fedex
2
- VERSION = "3.6.1"
2
+ VERSION = "3.8.0"
3
3
  API_VERSION = "13"
4
+ PICKUP_API_VERSION = "5"
5
+ SERVICE_AVAILABILITY_API_VERSION = "5"
4
6
  end
@@ -26,11 +26,11 @@ module Fedex
26
26
  it "validates the address" do
27
27
  address = fedex.validate_address(options)
28
28
 
29
- address.residential.should be_true
30
- address.business.should be_false
31
- address.score.should == 100
29
+ expect(address.residential).to be_truthy
30
+ expect(address.business).to be_falsey
31
+ expect(address.score).to eq(100)
32
32
 
33
- address.postal_code.should == "06850-3901"
33
+ expect(address.postal_code).to eq("06850-3901")
34
34
  end
35
35
  end
36
36
 
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Fedex
4
+ describe Shipment do
5
+ let (:fedex) { Shipment.new(fedex_credentials) }
6
+ context "#delete" do
7
+ context "delete shipment with tracking number", :vcr do
8
+ let(:options) do
9
+ { :tracking_number => '794608797150' }
10
+ end
11
+ it "deletes a shipment" do
12
+ expect{ fedex.delete(options) }.to_not raise_error
13
+ end
14
+ end
15
+ context "raise an error when the tracking number is invalid", :vcr do
16
+ let(:options) do
17
+ { :tracking_number => '111111111' }
18
+ end
19
+
20
+ it "raises an error" do
21
+ expect {fedex.delete(options) }.to raise_error(Fedex::RateError, 'Invalid tracking number')
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -108,23 +108,23 @@ module Fedex
108
108
  end
109
109
 
110
110
  it "saves a label to file" do
111
- File.should exist(filenames[:label])
111
+ expect(File).to exist(filenames[:label])
112
112
  end
113
113
 
114
114
  it "saves invoice to file" do
115
- File.should exist(filenames[:commercial_invoice])
115
+ expect(File).to exist(filenames[:commercial_invoice])
116
116
  end
117
117
 
118
118
  it "returns tracking number" do
119
- @document.should respond_to('tracking_number')
119
+ expect(@document).to respond_to('tracking_number')
120
120
  end
121
121
 
122
122
  it "exposes complete response" do
123
- @document.should respond_to('response_details')
123
+ expect(@document).to respond_to('response_details')
124
124
  end
125
125
 
126
126
  it "exposes the filenames" do
127
- @document.should respond_to('filenames')
127
+ expect(@document).to respond_to('filenames')
128
128
  end
129
129
 
130
130
  end
@@ -138,11 +138,11 @@ module Fedex
138
138
  end
139
139
 
140
140
  it "saves a label to file" do
141
- File.should exist(filenames[:label])
141
+ expect(File).to exist(filenames[:label])
142
142
  end
143
143
 
144
144
  it "has no others files" do
145
- File.should_not exist(filenames[:commercial_invoice])
145
+ expect(File).not_to exist(filenames[:commercial_invoice])
146
146
  end
147
147
 
148
148
  end
@@ -155,7 +155,7 @@ module Fedex
155
155
  end
156
156
 
157
157
  it "saves invoice to file" do
158
- File.should exist(filenames[:commercial_invoice])
158
+ expect(File).to exist(filenames[:commercial_invoice])
159
159
  end
160
160
  end
161
161
 
@@ -166,7 +166,7 @@ module Fedex
166
166
  end
167
167
 
168
168
  it "saves label to file" do
169
- File.should exist(filenames[:label])
169
+ expect(File).to exist(filenames[:label])
170
170
  end
171
171
  end
172
172
  end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ module Fedex
4
+ describe Shipment do
5
+ let (:fedex) { Shipment.new(fedex_credentials) }
6
+
7
+ let(:filename) {
8
+ require 'tmpdir'
9
+ File.join(Dir.tmpdir, "manifest#{rand(15000)}.txt")
10
+ }
11
+
12
+ context "#ground_close" do
13
+ context "with shipment ready for close", :vcr do
14
+ before do
15
+ shipper = { :name => "Sender", :company => "Company", :phone_number => "555-555-5555", :address => "Main Street", :city => "Harrison", :state => "AR", :postal_code => "72601", :country_code => "US" }
16
+ recipient = { :name => "Recipient", :company => "Company", :phone_number => "555-555-5555", :address => "Main Street", :city => "Frankin Park", :state => "IL", :postal_code => "60131", :country_code => "US", :residential => true }
17
+ packages = [
18
+ {
19
+ :weight => {:units => "LB", :value => 2},
20
+ :dimensions => {:length => 10, :width => 5, :height => 4, :units => "IN" }
21
+ }
22
+ ]
23
+ # require 'tmpdir'
24
+ # filename = File.join(Dir.tmpdir, "label#{rand(15000)}.pdf")
25
+ options = { :shipper => shipper, :recipient => recipient, :packages => packages, :service_type => "FEDEX_GROUND"}#, :filename => filename }
26
+ fedex.ship(options)
27
+ end
28
+
29
+ it "completes with success result" do
30
+ # When running this spec you may need to uncomment the line below to allow shipment to be created before close request
31
+ #sleep(7)
32
+ expect{ fedex.ground_close(:up_to_time => Time.now, :filename => filename) }.to_not raise_error
33
+ end
34
+ end
35
+ context "raise an error when there aren't any existing shipments to close", :vcr do
36
+ it "raises an error" do
37
+ expect { fedex.ground_close(:up_to_time => Time.now) }.to raise_error(Fedex::RateError, 'No Shipments to Close')
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -49,15 +49,15 @@ module Fedex
49
49
  end
50
50
 
51
51
  it "should create a label" do
52
- File.should exist(filename)
52
+ expect(File).to exist(filename)
53
53
  end
54
54
 
55
55
  it "should return tracking number" do
56
- @label.should respond_to('tracking_number')
56
+ expect(@label).to respond_to('tracking_number')
57
57
  end
58
58
 
59
59
  it "should expose complete response" do
60
- @label.should respond_to('response_details')
60
+ expect(@label).to respond_to('response_details')
61
61
  end
62
62
  after do
63
63
  require 'fileutils'
@@ -65,7 +65,7 @@ module Fedex
65
65
  end
66
66
 
67
67
  it "should expose the file_name" do
68
- @label.should respond_to('file_name')
68
+ expect(@label).to respond_to('file_name')
69
69
  end
70
70
  end
71
71
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+ require 'fedex/shipment'
3
+
4
+ describe Fedex::Request::Pickup do
5
+ describe "pickup availability service" do
6
+ let(:fedex) { Fedex::Shipment.new(fedex_credentials) }
7
+ let(:dispatch_date) {(Date.today + 1).strftime('%Y-%m-%d')}
8
+
9
+ let(:options) do
10
+ {:country_code => 'IN', :postal_code => '400061', :request_type => 'FUTURE_DAY', :dispatch_date => dispatch_date, :carrier_code => 'FDXE'}
11
+ end
12
+
13
+ it "succeeds", :vcr do
14
+ expect {
15
+ @pickup_availability = fedex.pickup_availability(options)
16
+ }.to_not raise_error
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ require 'fedex/shipment'
3
+
4
+ describe Fedex::Request::Pickup do
5
+ describe "pickup service" do
6
+ let(:fedex) { Fedex::Shipment.new(fedex_production_credentials) }
7
+ let(:pickup_location) do
8
+ {:name => "Sender", :company => "Company", :phone_number => "555-555-5555 ", :address => "Main Street",
9
+ :city => "Mumbai", :state => "MH", :postal_code => "400012", :country_code => "IN"}
10
+ end
11
+ let(:packages) do
12
+ {:weight => {:units => "LB", :value => 2}, :count => 2}
13
+ end
14
+ let(:ready_timestamp) { DateTime.now + 1 }
15
+ let(:close_time) { DateTime.now + 1.2 }
16
+
17
+ context "alternate address", :vcr do
18
+ let(:options) do
19
+ {:carrier_code => "FDXE", :packages => packages, :ready_timestamp => ready_timestamp,
20
+ :close_time => close_time, :pickup_location => pickup_location, :remarks => 'TEST. DO NOT PICKUP', :commodity_description => 'Ladies Item as per invoice',
21
+ :country_relationship => 'DOMESTIC'
22
+ }
23
+ end
24
+
25
+ it "succeeds" do
26
+ expect {
27
+ @pickup = fedex.pickup(options)
28
+ }.to_not raise_error
29
+ end
30
+ end
31
+ end
32
+ end
@@ -4,14 +4,14 @@ module Fedex
4
4
  describe Shipment do
5
5
  context "missing required parameters" do
6
6
  it "should raise Rate exception" do
7
- lambda{ Shipment.new}.should raise_error(RateError)
7
+ expect{ Shipment.new}.to raise_error(RateError)
8
8
  end
9
9
  end
10
10
 
11
11
  context "required parameters present" do
12
12
  subject { Shipment.new(fedex_credentials) }
13
13
  it "should create a valid instance" do
14
- subject.should be_an_instance_of(Shipment)
14
+ expect(subject).to be_an_instance_of(Shipment)
15
15
  end
16
16
  end
17
17
 
@@ -42,7 +42,11 @@ module Fedex
42
42
  context "domestic shipment", :vcr do
43
43
  it "should return a rate" do
44
44
  rates = fedex.rate({ :shipper => shipper, :recipient => recipient, :packages => packages, :service_type => "FEDEX_GROUND"})
45
- rates.first.should be_an_instance_of(Rate)
45
+ expect(rates.first).to be_an_instance_of(Rate)
46
+ end
47
+ it "should return a transit time" do
48
+ rates = fedex.rate({ :shipper => shipper, :recipient => recipient, :packages => packages, :service_type => "FEDEX_GROUND"})
49
+ expect(rates.first.transit_time).not_to be_nil
46
50
  end
47
51
  end
48
52
 
@@ -50,7 +54,7 @@ module Fedex
50
54
  it "should return a rate" do
51
55
  canadian_recipient = { :name => "Recipient", :company => "Company", :phone_number => "555-555-5555", :address=>"Address Line 1", :city => "Richmond", :state => "BC", :postal_code => "V7C4V4", :country_code => "CA", :residential => "true" }
52
56
  rates = fedex.rate({ :shipper => shipper, :recipient => canadian_recipient, :packages => packages, :service_type => "FEDEX_GROUND" })
53
- rates.first.should be_an_instance_of(Rate)
57
+ expect(rates.first).to be_an_instance_of(Rate)
54
58
  end
55
59
  end
56
60
 
@@ -141,7 +145,7 @@ module Fedex
141
145
 
142
146
  customs_clearance = { :broker => broker, :clearance_brokerage => clearance_brokerage, :importer_of_record => importer_of_record, :recipient_customs_id => recipient_customs_id, :duties_payment => duties_payment, :commodities => commodities }
143
147
  rates = fedex.rate({ :shipper => shipper, :recipient => canadian_recipient, :packages => packages, :service_type => "FEDEX_GROUND", :customs_clearance => customs_clearance })
144
- rates.first.should be_an_instance_of(Rate)
148
+ expect(rates.first).to be_an_instance_of(Rate)
145
149
  end
146
150
  end
147
151
 
@@ -157,7 +161,7 @@ module Fedex
157
161
  }
158
162
 
159
163
  it "returns a single rate" do
160
- rates.count.should eq 1
164
+ expect(rates.count).to eq 1
161
165
  end
162
166
 
163
167
  it "has service_type attribute" do
@@ -177,13 +181,13 @@ module Fedex
177
181
  }
178
182
 
179
183
  it "returns multiple rates" do
180
- rates.count.should >= 1
184
+ expect(rates.count).to be >= 1
181
185
  end
182
186
 
183
187
  context "each rate" do
184
188
 
185
189
  it 'has service type attribute' do
186
- rates.first.should respond_to(:service_type)
190
+ expect(rates.first).to respond_to(:service_type)
187
191
  end
188
192
 
189
193
  end
@@ -202,11 +206,11 @@ module Fedex
202
206
  }
203
207
 
204
208
  it 'returns empty array' do
205
- rates.should eq []
209
+ expect(rates).to eq []
206
210
  end
207
211
 
208
212
  end
209
213
 
210
214
  end
211
215
  end
212
- end
216
+ end