Skip to content
Browse files

sometimes fedex gives us a transit time in words and no delivery time…

…stamp. in this case, we parse the transit time and calculate a delivery date range from that.
  • Loading branch information...
1 parent 3e5b411 commit 57cc1013c4269ae95f6a1aedb9864e87ac4aff9b @orenmazor orenmazor committed
View
33 lib/active_shipping/shipping/carriers/fedex.rb
@@ -1,6 +1,7 @@
# FedEx module by Jimmy Baker
# http://github.com/jimmyebaker
+require 'date'
module ActiveMerchant
module Shipping
@@ -85,6 +86,9 @@ class FedEx < Carrier
'express_mps_master' => 'EXPRESS_MPS_MASTER'
}
+
+ TransitTimes = ["UNKNOWN","ONE_DAYS","TWO_DAYS","THREE_DAYS","FOUR_DAYS","FIVE_DAYS","SIX_DAYS","SEVEN_DAYS","EIGHT_DAYS","NINE_DAYS","TEN_DAYS","ELEVEN_DAYS","TWELVE_DAYS","THIRTEEN_DAYS","FOURTEEN_DAYS","FIFTEEN_DAYS","SIXTEEN_DAYS","SEVENTEEN_DAYS","EIGHTEEN_DAYS"]
+
# FedEx tracking codes as described in the FedEx Tracking Service WSDL Guide
# All delays also have been marked as exceptions
TRACKING_STATUS_CODES = HashWithIndifferentAccess.new({
@@ -136,7 +140,7 @@ def find_rates(origin, destination, packages, options = {})
rate_request = build_rate_request(origin, destination, packages, options)
response = commit(save_request(rate_request), (options[:test] || false)).gsub(/<(\/)?.*?\:(.*?)>/, '<\1\2>')
-
+
parse_rate_response(origin, destination, packages, response, options)
end
@@ -272,6 +276,20 @@ def parse_rate_response(origin, destination, packages, response, options)
is_saturday_delivery = rated_shipment.get_text('AppliedOptions').to_s == 'SATURDAY_DELIVERY'
service_type = is_saturday_delivery ? "#{service_code}_SATURDAY_DELIVERY" : service_code
+ transit_time = rated_shipment.get_text('TransitTime').to_s if service_code == "FEDEX_GROUND"
+ max_transit_time = rated_shipment.get_text('MaximumTransitTime').to_s if service_code == "FEDEX_GROUND"
+
+ delivery_timestamp = rated_shipment.get_text('DeliveryTimestamp').to_s
+
+ delivery_range = []
+ #if there's no delivery timestamp but we do have a transit time, use it
+ if delivery_timestamp.blank? and transit_time.present?
+ transit_range = parse_transit_times([transit_time,max_transit_time.presence || transit_time])
+ delivery_range = [Date.today + transit_range[0], Date.today + transit_range[1]]
+ else
+ delivery_range = [delivery_timestamp,delivery_timestamp]
+ end
+
currency = handle_incorrect_currency_codes(rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Currency').to_s)
rate_estimates << RateEstimate.new(origin, destination, @@name,
self.class.service_name_for_code(service_type),
@@ -279,8 +297,8 @@ def parse_rate_response(origin, destination, packages, response, options)
:total_price => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').to_s.to_f,
:currency => currency,
:packages => packages,
- :delivery_range => [rated_shipment.get_text('DeliveryTimestamp').to_s] * 2)
- end
+ :delivery_range => delivery_range)
+ end
if rate_estimates.empty?
success = false
@@ -390,6 +408,15 @@ def handle_incorrect_currency_codes(currency)
else currency
end
end
+
+ def parse_transit_times(times)
+ results = []
+ times.each do |day_count|
+ days = TransitTimes.index(day_count.to_s.chomp)
+ results << days.to_i
+ end
+ results
+ end
end
end
end
View
6 test/fixtures.yml
@@ -5,9 +5,11 @@ ups:
login: UPSDotComLogin
password: UPSDotComPassword
fedex:
- login: FedExAccountNumber
- password: FedExMeterNumber
+ account: FedExAccountNumber
+ login: FedExMeterNumber
+ password: FedExMeterPassword
test: true
+ key: FedExDeveloperKey
shipwire:
login: EmailAddress
password: Password
View
213 test/fixtures/xml/fedex/raterequest_reply.xml
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<v6:RateReply xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:v6="http://fedex.com/ws/rate/v6">
+ <v6:HighestSeverity>WARNING</v6:HighestSeverity>
+ <v6:Notifications>
+ <v6:Severity>WARNING</v6:Severity>
+ <v6:Source>crs</v6:Source>
+ <v6:Code>872</v6:Code>
+ <v6:Message>Rating is temporarily unavailable for one or more services:
+INTERNATIONAL_FIRST; INTERNATIONAL_PRIORITY; INTERNATIONAL_ECONOMY; ; ; ; ; ; ; ; . Please try again later. </v6:Message>
+ <v6:LocalizedMessage>Rating is temporarily unavailable for one or more services:
+INTERNATIONAL_FIRST; INTERNATIONAL_PRIORITY; INTERNATIONAL_ECONOMY; ; ; ; ; ; ; ; . Please try again later. </v6:LocalizedMessage>
+ <v6:MessageParameters>
+ <v6:Id>SERVICE_TYPE_1</v6:Id>
+ <v6:Value>INTERNATIONAL_FIRST</v6:Value>
+ </v6:MessageParameters>
+ <v6:MessageParameters>
+ <v6:Id>SERVICE_TYPE_2</v6:Id>
+ <v6:Value>INTERNATIONAL_PRIORITY</v6:Value>
+ </v6:MessageParameters>
+ <v6:MessageParameters>
+ <v6:Id>SERVICE_TYPE_3</v6:Id>
+ <v6:Value>INTERNATIONAL_ECONOMY</v6:Value>
+ </v6:MessageParameters>
+ </v6:Notifications>
+ <v6:Notifications>
+ <v6:Severity>NOTE</v6:Severity>
+ <v6:Source>crs</v6:Source>
+ <v6:Code>886</v6:Code>
+ <v6:Message>Money Back Guarantee is not eligible for this pick up/delivery postal/zip code</v6:Message>
+ <v6:LocalizedMessage>Money Back Guarantee is not eligible for this pick up/delivery postal/zip code</v6:LocalizedMessage>
+ </v6:Notifications>
+ <v6:TransactionDetail>
+ <v6:CustomerTransactionId>ActiveShipping</v6:CustomerTransactionId>
+ </v6:TransactionDetail>
+ <v6:Version>
+ <v6:ServiceId>crs</v6:ServiceId>
+ <v6:Major>6</v6:Major>
+ <v6:Intermediate>0</v6:Intermediate>
+ <v6:Minor>0</v6:Minor>
+ </v6:Version>
+ <v6:RateReplyDetails>
+ <v6:ServiceType>FEDEX_GROUND</v6:ServiceType>
+ <v6:PackagingType>YOUR_PACKAGING</v6:PackagingType>
+ <v6:DeliveryStation>CCDA </v6:DeliveryStation>
+ <v6:CommitDetails>
+ <v6:ServiceType>FEDEX_GROUND</v6:ServiceType>
+ <v6:TransitTime>FIVE_DAYS</v6:TransitTime>
+ <v6:BrokerToDestinationDays>0</v6:BrokerToDestinationDays>
+ </v6:CommitDetails>
+ <v6:DestinationAirportId>LAX</v6:DestinationAirportId>
+ <v6:IneligibleForMoneyBackGuarantee>true</v6:IneligibleForMoneyBackGuarantee>
+ <v6:OriginServiceArea>A1</v6:OriginServiceArea>
+ <v6:DestinationServiceArea>A1</v6:DestinationServiceArea>
+ <v6:TransitTime>FIVE_DAYS</v6:TransitTime>
+ <v6:SignatureOption>SERVICE_DEFAULT</v6:SignatureOption>
+ <v6:ActualRateType>PAYOR_ACCOUNT</v6:ActualRateType>
+ <v6:RatedShipmentDetails>
+ <v6:ShipmentRateDetail>
+ <v6:RateType>PAYOR_ACCOUNT</v6:RateType>
+ <v6:RateZone>53</v6:RateZone>
+ <v6:DimDivisor>0</v6:DimDivisor>
+ <v6:FuelSurchargePercent>5.25</v6:FuelSurchargePercent>
+ <v6:TotalBillingWeight>
+ <v6:Units>LB</v6:Units>
+ <v6:Value>10.0</v6:Value>
+ </v6:TotalBillingWeight>
+ <v6:TotalBaseCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>36.45</v6:Amount>
+ </v6:TotalBaseCharge>
+ <v6:TotalFreightDiscounts>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalFreightDiscounts>
+ <v6:TotalNetFreight>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>36.45</v6:Amount>
+ </v6:TotalNetFreight>
+ <v6:TotalSurcharges>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>1.91</v6:Amount>
+ </v6:TotalSurcharges>
+ <v6:TotalNetFedExCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>38.36</v6:Amount>
+ </v6:TotalNetFedExCharge>
+ <v6:TotalTaxes>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalTaxes>
+ <v6:TotalNetCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>38.36</v6:Amount>
+ </v6:TotalNetCharge>
+ <v6:TotalRebates>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalRebates>
+ <v6:Surcharges>
+ <v6:SurchargeType>FUEL</v6:SurchargeType>
+ <v6:Level>PACKAGE</v6:Level>
+ <v6:Description>FedEx Ground Fuel</v6:Description>
+ <v6:Amount>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>1.91</v6:Amount>
+ </v6:Amount>
+ </v6:Surcharges>
+ </v6:ShipmentRateDetail>
+ <v6:RatedPackages>
+ <v6:PackageRateDetail>
+ <v6:RateType>PAYOR_ACCOUNT</v6:RateType>
+ <v6:RatedWeightMethod>ACTUAL</v6:RatedWeightMethod>
+ <v6:BillingWeight>
+ <v6:Units>KG</v6:Units>
+ <v6:Value>1.0</v6:Value>
+ </v6:BillingWeight>
+ <v6:BaseCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>14.31</v6:Amount>
+ </v6:BaseCharge>
+ <v6:TotalFreightDiscounts>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalFreightDiscounts>
+ <v6:NetFreight>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>14.31</v6:Amount>
+ </v6:NetFreight>
+ <v6:TotalSurcharges>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.75</v6:Amount>
+ </v6:TotalSurcharges>
+ <v6:NetFedExCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>15.06</v6:Amount>
+ </v6:NetFedExCharge>
+ <v6:TotalTaxes>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalTaxes>
+ <v6:NetCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>15.06</v6:Amount>
+ </v6:NetCharge>
+ <v6:TotalRebates>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalRebates>
+ <v6:Surcharges>
+ <v6:SurchargeType>FUEL</v6:SurchargeType>
+ <v6:Level>PACKAGE</v6:Level>
+ <v6:Description>FedEx Ground Fuel</v6:Description>
+ <v6:Amount>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.75</v6:Amount>
+ </v6:Amount>
+ </v6:Surcharges>
+ </v6:PackageRateDetail>
+ </v6:RatedPackages>
+ <v6:RatedPackages>
+ <v6:PackageRateDetail>
+ <v6:RateType>PAYOR_ACCOUNT</v6:RateType>
+ <v6:RatedWeightMethod>ACTUAL</v6:RatedWeightMethod>
+ <v6:BillingWeight>
+ <v6:Units>KG</v6:Units>
+ <v6:Value>4.0</v6:Value>
+ </v6:BillingWeight>
+ <v6:BaseCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>22.14</v6:Amount>
+ </v6:BaseCharge>
+ <v6:TotalFreightDiscounts>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalFreightDiscounts>
+ <v6:NetFreight>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>22.14</v6:Amount>
+ </v6:NetFreight>
+ <v6:TotalSurcharges>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>1.16</v6:Amount>
+ </v6:TotalSurcharges>
+ <v6:NetFedExCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>23.3</v6:Amount>
+ </v6:NetFedExCharge>
+ <v6:TotalTaxes>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalTaxes>
+ <v6:NetCharge>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>23.3</v6:Amount>
+ </v6:NetCharge>
+ <v6:TotalRebates>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>0.0</v6:Amount>
+ </v6:TotalRebates>
+ <v6:Surcharges>
+ <v6:SurchargeType>FUEL</v6:SurchargeType>
+ <v6:Level>PACKAGE</v6:Level>
+ <v6:Description>FedEx Ground Fuel</v6:Description>
+ <v6:Amount>
+ <v6:Currency>CAD</v6:Currency>
+ <v6:Amount>1.16</v6:Amount>
+ </v6:Amount>
+ </v6:Surcharges>
+ </v6:PackageRateDetail>
+ </v6:RatedPackages>
+ </v6:RatedShipmentDetails>
+ </v6:RateReplyDetails>
+</v6:RateReply>
View
14 test/unit/carriers/fedex_test.rb
@@ -204,4 +204,18 @@ def test_delivery_range_based_on_delivery_date
assert_equal delivery_date, rate_estimates.rates[0].delivery_date
assert_equal [delivery_date] * 2, rate_estimates.rates[0].delivery_range
end
+
+ def test_delivery_date_from_transit_time
+ mock_response = xml_fixture('fedex/raterequest_reply').gsub('CAD', 'UKL')
+
+ @carrier.expects(:commit).returns(mock_response)
+ rate_estimates = @carrier.find_rates( @locations[:ottawa],
+ @locations[:beverly_hills],
+ @packages.values_at(:book, :wii), :test => true)
+
+ #the above fixture will specify a transit time of 5 days
+ delivery_date = Date.today + 5
+ assert_equal delivery_date, rate_estimates.rates[0].delivery_date
+ end
+
end

0 comments on commit 57cc101

Please sign in to comment.
Something went wrong with that request. Please try again.