Class: FriendlyShipping::Services::UspsInternational::ParsePackageRate
- Inherits:
-
Object
- Object
- FriendlyShipping::Services::UspsInternational::ParsePackageRate
- Defined in:
- lib/friendly_shipping/services/usps_international/parse_package_rate.rb
Constant Summary collapse
- ESCAPING_AND_SYMBOLS =
USPS returns all the info about a rate in a long string with a bit of gibberish.
/<\S*>/
- LEADING_USPS =
At the beginning of the long String, USPS keeps a copy of its own name. We know we're dealing with them though, so we can filter that out, too.
/^USPS /
- SERVICE_NAME_SUBSTITUTIONS =
This combines all the things we want to filter out.
/#{ESCAPING_AND_SYMBOLS}|#{LEADING_USPS}/
- SERVICE_CODE_TAG =
Often we get a multitude of rates for the same service given some combination of Box type and (see below) and "Hold for Pickup" service. This creates a regular expression with groups named after the keys from the
Usps::CONTAINERS
constant. Unfortunately, the keys don't correspond directly to the codes we use when serializing the request. The tags used in the rate node that we get information from. 'ID'
- SERVICE_NAME_TAG =
'SvcDescription'
- RATE_TAG =
'Postage'
- COMMERCIAL_RATE_TAG =
'CommercialPostage'
- COMMERCIAL_PLUS_RATE_TAG =
'CommercialPlusPostage'
- CURRENCY =
Money::Currency.new('USD').freeze
Class Method Summary collapse
Class Method Details
.call(rate_node, package, package_options) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/friendly_shipping/services/usps_international/parse_package_rate.rb', line 31 def call(rate_node, package, ) # "A mail class identifier for the postage returned. Not necessarily unique within a <Package/>." # (from the USPS docs). We save this on the data Hash, but do not use it for identifying shipping methods. service_code = rate_node.attributes[SERVICE_CODE_TAG].value # The long string discussed above. service_name = rate_node.at(SERVICE_NAME_TAG).text delivery_guarantee = rate_node.at('GuaranteeAvailability')&.text delivery_commitment = rate_node.at('SvcCommitments')&.text # Clean up the long string service_name.gsub!(SERVICE_NAME_SUBSTITUTIONS, '') commercial_rate_requested_or_rate_is_zero = .commercial_pricing || rate_node.at(RATE_TAG).text.to_d.zero? commercial_rate_available = rate_node.at(COMMERCIAL_RATE_TAG) || rate_node.at(COMMERCIAL_PLUS_RATE_TAG) rate_value = if commercial_rate_requested_or_rate_is_zero && commercial_rate_available commercial_rate = rate_node.at(COMMERCIAL_RATE_TAG)&.text.to_d commercial_rate.zero? ? rate_node.at(COMMERCIAL_PLUS_RATE_TAG).text.to_d : commercial_rate else rate_node.at(RATE_TAG).text.to_d end # The rate expressed as a RubyMoney objext rate = Money.new(rate_value * CURRENCY.subunit_to_unit, CURRENCY) # Which shipping method does this rate belong to? We first try to match a rate to a shipping method shipping_method = SHIPPING_METHODS.find { |sm| sm.service_code == service_code } # Combine all the gathered information in a FriendlyShipping::Rate object. # Careful: This rate is only for one package within the shipment, and we get multiple # rates per package for the different shipping method/box/hold for pickup combinations. FriendlyShipping::Rate.new( shipping_method: shipping_method, amounts: { package.id => rate }, data: { package: package, delivery_commitment: delivery_commitment, delivery_guarantee: delivery_guarantee, full_mail_service: service_name, service_code: service_code, } ) end |