Class: FriendlyShipping::Services::UpsJson::GeneratePackageHash

Inherits:
Object
  • Object
show all
Defined in:
lib/friendly_shipping/services/ups_json/generate_package_hash.rb

Class Method Summary collapse

Class Method Details

.call(package:, delivery_confirmation_code: nil, shipper_release: false, transmit_dimensions: true, declared_value: false, package_flavor: nil, reference_numbers: nil) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
# File 'lib/friendly_shipping/services/ups_json/generate_package_hash.rb', line 8

def call(package:,
         delivery_confirmation_code: nil,
         shipper_release: false,
         transmit_dimensions: true,
         declared_value: false,
         package_flavor: nil,
         reference_numbers: nil)
  # UPS consistency across apis is a bit of a mess
  packaging_type_key = package_flavor == "rates" ? :PackagingType : :Packaging

  package_hash = {
    packaging_type_key => {
      Code: "02"
    },
    PackageWeight: {
      UnitOfMeasurement: {
        Code: "LBS"
      },
      Weight: [package.weight.convert_to(:pounds).value.to_f.round(2), 1].max.to_s
    },
    PackageServiceOptions: {},
    Description: package.items.map(&:description).compact.uniq.join(', ').slice(0, 35) # required for return labels
  }

  if transmit_dimensions && package.dimensions.all? { |dim| !dim.value.zero? && !dim.value.infinite? }
    package_hash[:Dimensions] = {
      UnitOfMeasurement: {
        Code: "IN"
      },
      Length: package.length.convert_to(:inches).value.to_f.round(2).to_s,
      Width: package.width.convert_to(:inches).value.to_f.round(2).to_s,
      Height: package.height.convert_to(:inches).value.to_f.round(2).to_s
    }
  end

  package_hash[:PackageServiceOptions][:ShipperReleaseIndicator] = true if shipper_release
  if delivery_confirmation_code
    package_hash[:PackageServiceOptions][:DeliveryConfirmation] = { DCISType: delivery_confirmation_code }
  end

  total_value = package.items.inject(Money.new(0, "USD")) do |package_sum, item|
    package_sum + (item.cost || Money.new(0, "USD"))
  end

  # this key is invalid for labels, UPS responds with "Accessory may not be combined with the product."
  if package_flavor == "rates" && declared_value
    package_hash[:PackageServiceOptions][:DeclaredValue] = {
      CurrencyCode: total_value.currency.iso_code,
      MonetaryValue: total_value.to_s
    }
  end

  if reference_numbers.present?
    package_hash[:ReferenceNumber] = reference_numbers.map do |code, value|
      {
        Code: code.to_s,
        Value: value.to_s
      }
    end
  end

  package_hash[:PackageServiceOptions].compact_blank!
  package_hash.compact_blank!
end