Skip to content

Loading…

Not including insured value for UPS #52

Open
pwoltman opened this Issue · 1 comment

2 participants

@pwoltman

ActiveShipping currently is ignoring the package monetary values/currency when calculating shipping charges for UPS. Updating the build_rate_request method to include PackageServiceOptions with DeclaredValue and InsuredValue will result in the returned rates including the insurance cost in the total (see code below)

module ActiveMerchant
  module Shipping
    class UPS < Carrier
      protected
      def build_rate_request(origin, destination, packages, options={})
        packages = Array(packages)
        xml_request = XmlNode.new('RatingServiceSelectionRequest') do |root_node|
          root_node << XmlNode.new('Request') do |request|
            request << XmlNode.new('RequestAction', 'Rate')
            request << XmlNode.new('RequestOption', 'Shop')
            # not implemented: 'Rate' RequestOption to specify a single service query
            # request << XmlNode.new('RequestOption', ((options[:service].nil? or options[:service] == :all) ? 'Shop' : 'Rate'))
          end

          pickup_type = options[:pickup_type] || :daily_pickup

          root_node << XmlNode.new('PickupType') do |pickup_type_node|
            pickup_type_node << XmlNode.new('Code', PICKUP_CODES[pickup_type])
            # not implemented: PickupType/PickupDetails element
          end
          cc = options[:customer_classification] || DEFAULT_CUSTOMER_CLASSIFICATIONS[pickup_type]
          root_node << XmlNode.new('CustomerClassification') do |cc_node|
            cc_node << XmlNode.new('Code', CUSTOMER_CLASSIFICATIONS[cc])
          end

          root_node << XmlNode.new('Shipment') do |shipment|
            # not implemented: Shipment/Description element
            shipment << build_location_node('Shipper', (options[:shipper] || origin), options)
            shipment << build_location_node('ShipTo', destination, options)
            if options[:shipper] and options[:shipper] != origin
              shipment << build_location_node('ShipFrom', origin, options)
            end

            # not implemented:  * Shipment/ShipmentWeight element
            #                   * Shipment/ReferenceNumber element                    
            #                   * Shipment/Service element                            
            #                   * Shipment/PickupDate element                         
            #                   * Shipment/ScheduledDeliveryDate element              
            #                   * Shipment/ScheduledDeliveryTime element              
            #                   * Shipment/AlternateDeliveryTime element              
            #                   * Shipment/DocumentsOnly element                      

            packages.each do |package|
              imperial = ['US','LR','MM'].include?(origin.country_code(:alpha2))

              shipment << XmlNode.new("Package") do |package_node|

                # not implemented:  * Shipment/Package/PackagingType element
                #                   * Shipment/Package/Description element

                package_node << XmlNode.new("PackagingType") do |packaging_type|
                  packaging_type << XmlNode.new("Code", '02')
                end

                package_node << XmlNode.new("Dimensions") do |dimensions|
                  dimensions << XmlNode.new("UnitOfMeasurement") do |units|
                    units << XmlNode.new("Code", imperial ? 'IN' : 'CM')
                  end
                  [:length,:width,:height].each do |axis|
                    value = ((imperial ? package.inches(axis) : package.cm(axis)).to_f*1000).round/1000.0 # 3 decimals
                    dimensions << XmlNode.new(axis.to_s.capitalize, [value,0.1].max)
                  end
                end

                package_node << XmlNode.new("PackageWeight") do |package_weight|
                  package_weight << XmlNode.new("UnitOfMeasurement") do |units|
                    units << XmlNode.new("Code", imperial ? 'LBS' : 'KGS')
                  end

                  value = ((imperial ? package.lbs : package.kgs).to_f*1000).round/1000.0 # 3 decimals
                  package_weight << XmlNode.new("Weight", [value,0.1].max)
                end

                package_node << XmlNode.new("PackageServiceOptions") do |package_service_options|
                  package_service_options << XmlNode.new("DeclaredValue") do |declared_value|
                    declared_value << XmlNode.new("CurrencyCode", package.currency)
                    declared_value << XmlNode.new("MonetaryValue", (package.value.to_i/100)) 
                  end
                  package_service_options << XmlNode.new("InsuredValue") do |declared_value|
                    declared_value << XmlNode.new("CurrencyCode", package.currency)
                    declared_value << XmlNode.new("MonetaryValue", (package.value.to_i/100)) 
                  end
                end
                # not implemented:  * Shipment/Package/LargePackageIndicator element
                #                   * Shipment/Package/ReferenceNumber element
                #                   * Shipment/Package/PackageServiceOptions element
                #                   * Shipment/Package/AdditionalHandling element  
              end

            end

            # not implemented:  * Shipment/ShipmentServiceOptions element
            #                   * Shipment/RateInformation element

          end

        end
        xml_request.to_s
      end
    end
  end
end
@csaunders

Could you create the patch and issue a PR instead? It's really difficult to see the code changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.