fedex 3.6.1 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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