lib/friendly_shipping/services/ups/serialize_shipment_confirm_request.rb
# Item options (only necessary for international shipping)
#
# @option description [String] A description of the item for the intl. invoice
# @option commodity_code [String] Commodity code for the item. See https://www.tariffnumber.com/
# @option value [Money] Price of the item
# @option unit_of_item_count [String] What kind of thing is one of this item? Example: Barrel, m3.
#   See UPS docs for codes.
#
Item options (only necessary for international shipping)
Item options ( only necessary for international shipping )
def call(
            shipment:,
            options:
          )
            xml_builder = Nokogiri::XML::Builder.new do |xml|
              xml.ShipmentConfirmRequest do
                xml.Request do
                  xml.RequestAction('ShipConfirm')
                  xml.RequestOption(options.validate_address ? 'validate' : 'nonvalidate')
                  xml.SubVersion('1707')
                  if options.customer_context
                    xml.TransactionReference do
                      xml.CustomerContext(options.customer_context)
                    end
                  end
                end
                xml.Shipment do
                  xml.Service do
                    xml.Code(options.shipping_method.service_code)
                  end
                  xml.ShipTo do
                    SerializeShipmentAddressSnippet.call(xml: xml, location: shipment.destination)
                  end
                  xml.Shipper do
                    SerializeShipmentAddressSnippet.call(xml: xml, location: options.shipper || shipment.origin)
                    xml.ShipperNumber(options.shipper_number)
                  end
                  if options.shipper || options.return_service_code
                    origin = options.return_service_code ? shipment.destination : shipment.origin
                    xml.ShipFrom do
                      SerializeShipmentAddressSnippet.call(xml: xml, location: origin)
                    end
                  end
                  if options.negotiated_rates
                    xml.RateInformation do
                      xml.NegotiatedRatesIndicator
                    end
                  end
                  if options.billing_options.prepay
                    xml.PaymentInformation do
                      xml.Prepaid do
                        build_billing_info_node(xml, options)
                      end
                    end
                  else
                    xml.ItemizedPaymentInformation do
                      xml.ShipmentCharge do
                        xml.Type('01')
                        build_billing_info_node(xml, options)
                      end
                      if international?(shipment) && options.terms_of_shipment_code == 'DDP'
                        xml.ShipmentCharge do
                          xml.Type('02') 
                          build_billing_info_node(
                            xml,
                            options,
                            bill_to_consignee: true
                          )
                        end
                      end
                    end
                  end
                  if international?(shipment)
                    unless options.return_service_code
                      xml.SoldTo do
                        sold_to_location = options.sold_to || shipment.destination
                        SerializeShipmentAddressSnippet.call(xml: xml, location: sold_to_location)
                      end
                    end
                    if shipment.origin.country.code == 'US' && ['CA', 'PR'].include?(shipment.destination.country.code)
                      xml.InvoiceLineTotal do
                        total_value = shipment.packages.inject(Money.new(0, 'USD')) do |shipment_sum, package|
                          shipment_sum + package.items.inject(Money.new(0, 'USD')) do |package_sum, item|
                            package_sum + (item.cost || Money.new(0, 'USD'))
                          end
                        end
                        xml.MonetaryValue(total_value.to_f)
                      end
                    end
                    contents_description = shipment.packages.flat_map do |package|
                      package.items.map(&:description)
                    end.compact.join(', ')
                    unless contents_description.empty?
                      xml.Description(contents_description)
                    end
                  end
                  if options.return_service_code
                    xml.ReturnService do
                      xml.Code(options.return_service_code)
                    end
                  end
                  xml.ShipmentServiceOptions do
                    xml.SaturdayDelivery if options.saturday_delivery
                    xml.UPScarbonneutralIndicator if options.carbon_neutral
                    if options.delivery_confirmation_code
                      xml.DeliveryConfirmation do
                        xml.DCISType(options.delivery_confirmation_code)
                      end
                    end
                    if international?(shipment)
                      build_international_forms(xml, shipment, options)
                    end
                  end
                  shipment.packages.each do |package|
                    package_options = options.options_for_package(package)
                    reference_numbers = allow_package_level_reference_numbers(shipment) ? package_options.reference_numbers : {}
                    delivery_confirmation_code = package_level_delivery_confirmation?(shipment) ? package_options.delivery_confirmation_code : nil
                    SerializePackageNode.call(
                      xml: xml,
                      package: package,
                      reference_numbers: reference_numbers,
                      delivery_confirmation_code: delivery_confirmation_code,
                      shipper_release: package_options.shipper_release
                    )
                  end
                end
                xml.LabelSpecification do
                  xml.LabelStockSize do
                    xml.Height(options.label_size[0])
                    xml.Width(options.label_size[1])
                  end
                  xml.LabelPrintMethod do
                    xml.Code(options.label_format)
                  end
                  if options.label_format == 'GIF'
                    xml.HTTPUserAgent('Mozilla/4.5')
                    xml.LabelImageFormat(options.label_format) do
                      xml.Code(options.label_format)
                    end
                  end
                end
              end
            end
            xml_builder.to_xml
          end
def call ( shipment : , options : ) xml_builder = Nokogiri :: XML :: Builder . new do | xml | xml . ShipmentConfirmRequest do xml . Request do xml . RequestAction ( 'ShipConfirm' ) xml . RequestOption ( options . validate_address ? 'validate' : 'nonvalidate' ) xml . SubVersion ( '1707' ) if options . customer_context xml . TransactionReference do xml . CustomerContext ( options . customer_context ) end end end xml . Shipment do xml . Service do xml . Code ( options . shipping_method . service_code ) end xml . ShipTo do SerializeShipmentAddressSnippet . call ( xml : xml , location : shipment . destination ) end xml . Shipper do SerializeShipmentAddressSnippet . call ( xml : xml , location : options . shipper || shipment . origin ) xml . ShipperNumber ( options . shipper_number ) end if options . shipper || options . return_service_code origin = options . return_service_code ? shipment . destination : shipment . origin xml . ShipFrom do SerializeShipmentAddressSnippet . call ( xml : xml , location : origin ) end end if options . negotiated_rates xml . RateInformation do xml . NegotiatedRatesIndicator end end if options . billing_options . prepay xml . PaymentInformation do xml . Prepaid do build_billing_info_node ( xml , options ) end end else xml . ItemizedPaymentInformation do xml . ShipmentCharge do xml . Type ( '01' ) build_billing_info_node ( xml , options ) end if international? ( shipment ) && options . terms_of_shipment_code == 'DDP' xml . ShipmentCharge do xml . Type ( '02' ) build_billing_info_node ( xml , options , bill_to_consignee : true ) end end end end if international? ( shipment ) unless options . return_service_code xml . SoldTo do sold_to_location = options . sold_to || shipment . destination SerializeShipmentAddressSnippet . call ( xml : xml , location : sold_to_location ) end end if shipment . origin . country . code == 'US' && [ 'CA' , 'PR' ] . include? ( shipment . destination . country . code ) xml . InvoiceLineTotal do total_value = shipment . packages . inject ( Money . new ( 0 , 'USD' ) ) do | shipment_sum , package | shipment_sum + package . items . inject ( Money . new ( 0 , 'USD' ) ) do | package_sum , item | package_sum + ( item . cost || Money . new ( 0 , 'USD' ) ) end end xml . MonetaryValue ( total_value . to_f ) end end contents_description = shipment . packages . flat_map do | package | package . items . map ( & :description ) end . compact . join ( ', ' ) unless contents_description . empty? xml . Description ( contents_description ) end end if options . return_service_code xml . ReturnService do xml . Code ( options . return_service_code ) end end xml . ShipmentServiceOptions do xml . SaturdayDelivery if options . saturday_delivery xml . UPScarbonneutralIndicator if options . carbon_neutral if options . delivery_confirmation_code xml . DeliveryConfirmation do xml . DCISType ( options . delivery_confirmation_code ) end end if international? ( shipment ) build_international_forms ( xml , shipment , options ) end end shipment . packages . each do | package | package_options = options . options_for_package ( package ) reference_numbers = allow_package_level_reference_numbers ( shipment ) ? package_options . reference_numbers : { } delivery_confirmation_code = package_level_delivery_confirmation? ( shipment ) ? package_options . delivery_confirmation_code : nil SerializePackageNode . call ( xml : xml , package : package , reference_numbers : reference_numbers , delivery_confirmation_code : delivery_confirmation_code , shipper_release : package_options . shipper_release ) end end xml . LabelSpecification do xml . LabelStockSize do xml . Height ( options . label_size [ 0 ] ) xml . Width ( options . label_size [ 1 ] ) end xml . LabelPrintMethod do xml . Code ( options . label_format ) end if options . label_format == 'GIF' xml . HTTPUserAgent ( 'Mozilla/4.5' ) xml . LabelImageFormat ( options . label_format ) do xml . Code ( options . label_format ) end end end end end xml_builder . to_xml end
Item options (only necessary for international shipping)
Item options ( only necessary for international shipping )
# Required element controls level of address validation. # Optional element to identify transactions between client and server. # Required element. The company whose account is responsible for the label(s). # shipment.options.fetch(:reference_numbers, {}).each do |reference_code, reference_value| #   xml.ReferenceNumber do #     xml.Code(reference_code) #     xml.Value(reference_value) #   end # end # Type '01' means 'Transportation' # This node specifies who will be billed for transportation. # The shipper will cover duties and taxes # Otherwise UPS will charge the receiver # Type '02' means 'Duties and Taxes' # Required for shipments from the US to Puerto Rico or Canada # We'll assume USD as the origin country is the United States here. # API requires these only if returning a GIF formated label
shipment
<not_specific>
options
<not_specific>
description
<not_specific>
A description of the item for the intl. invoice
A description of the item for the intl . invoice
commodity_code
<not_specific>
Commodity code for the item.
Commodity code for the item .
value
<not_specific>
Price of the item
Price of the item
unit_of_item_count
<not_specific>
None