friendly_shipping 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.md +16 -16
  4. data/lib/friendly_shipping/services/rl/parse_rate_quote_response.rb +3 -3
  5. data/lib/friendly_shipping/services/ups_json/parse_money_hash.rb +1 -0
  6. data/lib/friendly_shipping/services/usps_international/parse_rate_response.rb +3 -3
  7. data/lib/friendly_shipping/services/{usps → usps_international}/parse_xml_response.rb +1 -1
  8. data/lib/friendly_shipping/services/usps_international/serialize_rate_request.rb +1 -1
  9. data/lib/friendly_shipping/services/usps_ship/parse_rate_estimates_response.rb +1 -1
  10. data/lib/friendly_shipping/version.rb +1 -1
  11. metadata +3 -51
  12. data/lib/friendly_shipping/services/ups/label.rb +0 -20
  13. data/lib/friendly_shipping/services/ups/label_billing_options.rb +0 -41
  14. data/lib/friendly_shipping/services/ups/label_item_options.rb +0 -75
  15. data/lib/friendly_shipping/services/ups/label_options.rb +0 -174
  16. data/lib/friendly_shipping/services/ups/label_package_options.rb +0 -49
  17. data/lib/friendly_shipping/services/ups/parse_address_classification_response.rb +0 -29
  18. data/lib/friendly_shipping/services/ups/parse_address_validation_response.rb +0 -53
  19. data/lib/friendly_shipping/services/ups/parse_city_state_lookup_response.rb +0 -33
  20. data/lib/friendly_shipping/services/ups/parse_modifier_element.rb +0 -29
  21. data/lib/friendly_shipping/services/ups/parse_money_element.rb +0 -128
  22. data/lib/friendly_shipping/services/ups/parse_rate_response.rb +0 -101
  23. data/lib/friendly_shipping/services/ups/parse_shipment_accept_response.rb +0 -77
  24. data/lib/friendly_shipping/services/ups/parse_shipment_confirm_response.rb +0 -24
  25. data/lib/friendly_shipping/services/ups/parse_time_in_transit_response.rb +0 -56
  26. data/lib/friendly_shipping/services/ups/parse_void_shipment_response.rb +0 -24
  27. data/lib/friendly_shipping/services/ups/parse_xml_response.rb +0 -50
  28. data/lib/friendly_shipping/services/ups/rate_estimate_options.rb +0 -111
  29. data/lib/friendly_shipping/services/ups/rate_estimate_package_options.rb +0 -22
  30. data/lib/friendly_shipping/services/ups/serialize_access_request.rb +0 -20
  31. data/lib/friendly_shipping/services/ups/serialize_address_snippet.rb +0 -60
  32. data/lib/friendly_shipping/services/ups/serialize_address_validation_request.rb +0 -40
  33. data/lib/friendly_shipping/services/ups/serialize_city_state_lookup_request.rb +0 -26
  34. data/lib/friendly_shipping/services/ups/serialize_package_node.rb +0 -75
  35. data/lib/friendly_shipping/services/ups/serialize_rating_service_selection_request.rb +0 -98
  36. data/lib/friendly_shipping/services/ups/serialize_shipment_accept_request.rb +0 -27
  37. data/lib/friendly_shipping/services/ups/serialize_shipment_address_snippet.rb +0 -21
  38. data/lib/friendly_shipping/services/ups/serialize_shipment_confirm_request.rb +0 -285
  39. data/lib/friendly_shipping/services/ups/serialize_time_in_transit_request.rb +0 -56
  40. data/lib/friendly_shipping/services/ups/serialize_void_shipment_request.rb +0 -21
  41. data/lib/friendly_shipping/services/ups/shipping_methods.rb +0 -111
  42. data/lib/friendly_shipping/services/ups/timing_options.rb +0 -33
  43. data/lib/friendly_shipping/services/ups.rb +0 -218
  44. data/lib/friendly_shipping/services/usps/choose_package_rate.rb +0 -40
  45. data/lib/friendly_shipping/services/usps/machinable_package.rb +0 -50
  46. data/lib/friendly_shipping/services/usps/parse_address_validation_response.rb +0 -43
  47. data/lib/friendly_shipping/services/usps/parse_city_state_lookup_response.rb +0 -41
  48. data/lib/friendly_shipping/services/usps/parse_package_rate.rb +0 -159
  49. data/lib/friendly_shipping/services/usps/parse_rate_response.rb +0 -86
  50. data/lib/friendly_shipping/services/usps/parse_time_in_transit_response.rb +0 -240
  51. data/lib/friendly_shipping/services/usps/rate_estimate_options.rb +0 -26
  52. data/lib/friendly_shipping/services/usps/rate_estimate_package_options.rb +0 -66
  53. data/lib/friendly_shipping/services/usps/serialize_address_validation_request.rb +0 -25
  54. data/lib/friendly_shipping/services/usps/serialize_city_state_lookup_request.rb +0 -20
  55. data/lib/friendly_shipping/services/usps/serialize_rate_request.rb +0 -83
  56. data/lib/friendly_shipping/services/usps/serialize_time_in_transit_request.rb +0 -22
  57. data/lib/friendly_shipping/services/usps/shipping_methods.rb +0 -66
  58. data/lib/friendly_shipping/services/usps/timing_options.rb +0 -19
  59. data/lib/friendly_shipping/services/usps.rb +0 -115
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- # Option container for rating a shipment via UPS
6
- #
7
- # Required:
8
- #
9
- # @option shipper_number [String] The shipper number of the origin of the shipment.
10
- #
11
- # Optional:
12
- #
13
- # @option carbon_neutral [Boolean] Ship with UPS' carbon neutral program
14
- # @option customer_context [String ] Optional element to identify transactions between client and server
15
- # @option customer_classification [Symbol] Which kind of rates to request. See UPS docs for more details. Default: `shipper_number`
16
- # @option negotiated_rates [Boolean] if truthy negotiated rates will be requested from ups. Only valid if
17
- # shipper account has negotiated rates. Default: false
18
- # @option pickup_type [String] UPS pickup type. See UPS docs for more details. Default: `daily_pickup`
19
- # @option pickup_date [Time] UPS pickup date/time. Default: nil
20
- # @option saturday_delivery [Boolean] should we request Saturday delivery?. Default: false
21
- # @option saturday_pickup [Boolean] should we request Saturday pickup?. Default: false
22
- # @option shipping_method [FriendlyShipping::ShippingMethod] Request rates for a particular shipping method only?
23
- # Default is `nil`, which translates to 'All shipping methods' (The "Shop" option in UPS parlance)
24
- # @option sub_version [String] The UPS API sub-version to use for requests. Default: 1707
25
- # @option with_time_in_transit [Boolean] Whether to request timing information alongside the rates
26
- # @option package_options_class [Class] See FriendlyShipping::ShipmentOptions
27
- #
28
- class Ups
29
- class RateEstimateOptions < FriendlyShipping::ShipmentOptions
30
- PICKUP_TYPE_CODES = {
31
- daily_pickup: "01",
32
- customer_counter: "03",
33
- one_time_pickup: "06",
34
- on_call_air: "07",
35
- suggested_retail_rates: "11",
36
- letter_center: "19",
37
- air_service_center: "20"
38
- }.freeze
39
-
40
- CUSTOMER_CLASSIFICATION_CODES = {
41
- shipper_number: "00",
42
- daily_rates: "01",
43
- retail_rates: "04",
44
- regional_rates: "05",
45
- general_rates: "06",
46
- standard_rates: "53"
47
- }.freeze
48
-
49
- SUB_VERSIONS = %w[1601 1607 1701 1707 1801 2108 2201 2205].freeze
50
-
51
- attr_reader :carbon_neutral,
52
- :customer_context,
53
- :destination_account,
54
- :negotiated_rates,
55
- :pickup_date,
56
- :saturday_delivery,
57
- :saturday_pickup,
58
- :shipper,
59
- :shipper_number,
60
- :shipping_method,
61
- :sub_version,
62
- :with_time_in_transit
63
-
64
- def initialize(
65
- shipper_number:,
66
- carbon_neutral: true,
67
- customer_context: nil,
68
- customer_classification: :daily_rates,
69
- destination_account: nil,
70
- negotiated_rates: false,
71
- pickup_type: :daily_pickup,
72
- pickup_date: nil,
73
- saturday_delivery: false,
74
- saturday_pickup: false,
75
- shipper: nil,
76
- shipping_method: nil,
77
- sub_version: "1707",
78
- with_time_in_transit: false,
79
- package_options_class: FriendlyShipping::Services::Ups::RateEstimatePackageOptions,
80
- **kwargs
81
- )
82
- raise ArgumentError, "Invalid sub-version: #{sub_version}" unless sub_version.in?(SUB_VERSIONS)
83
-
84
- @carbon_neutral = carbon_neutral
85
- @customer_context = customer_context
86
- @customer_classification = customer_classification
87
- @destination_account = destination_account
88
- @negotiated_rates = negotiated_rates
89
- @shipper_number = shipper_number
90
- @pickup_type = pickup_type
91
- @pickup_date = pickup_date
92
- @saturday_delivery = saturday_delivery
93
- @saturday_pickup = saturday_pickup
94
- @shipper = shipper
95
- @shipping_method = shipping_method
96
- @sub_version = sub_version
97
- @with_time_in_transit = with_time_in_transit
98
- super(**kwargs.reverse_merge(package_options_class: package_options_class))
99
- end
100
-
101
- def pickup_type_code
102
- PICKUP_TYPE_CODES[@pickup_type]
103
- end
104
-
105
- def customer_classification_code
106
- CUSTOMER_CLASSIFICATION_CODES[@customer_classification]
107
- end
108
- end
109
- end
110
- end
111
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- # Package properties relevant for quoting a UPS package
7
- #
8
- # @option transmit_dimensions [Boolean] Whether to transmit the dimensions of this package, or quote only based on weight.
9
- class RateEstimatePackageOptions < FriendlyShipping::PackageOptions
10
- attr_reader :transmit_dimensions
11
-
12
- def initialize(
13
- transmit_dimensions: true,
14
- **kwargs
15
- )
16
- @transmit_dimensions = transmit_dimensions
17
- super(**kwargs)
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeAccessRequest
7
- def self.call(login:, password:, key:)
8
- xml_builder = Nokogiri::XML::Builder.new do |xml|
9
- xml.AccessRequest do
10
- xml.AccessLicenseNumber(key)
11
- xml.UserId(login)
12
- xml.Password(password)
13
- end
14
- end
15
- xml_builder.to_xml
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeAddressSnippet
7
- class << self
8
- def call(xml:, location:, international: false)
9
- if international
10
- name = (location.company_name || location.name)[0..34]
11
- attention_name = location.name
12
- elsif location.company_name # Is this a business address?
13
- name = location.company_name[0..34]
14
- attention_name = location.name
15
- else
16
- name = location.name
17
- attention_name = nil
18
- end
19
-
20
- # UPS wants a different main Name tag when it's the shipper
21
- if xml.parent.name == "Shipper"
22
- xml.Name(name)
23
- else
24
- xml.CompanyName(name)
25
- end
26
-
27
- if attention_name
28
- xml.AttentionName(attention_name)
29
- end
30
-
31
- xml.PhoneNumber(location.phone) if location.phone
32
-
33
- xml.Address do
34
- xml.AddressLine1(location.address1) if location.address1
35
- xml.AddressLine2(location.address2) if location.address2
36
-
37
- xml.City(location.city) if location.city
38
- xml.PostalCode(location.zip) if location.zip
39
-
40
- # StateProvinceCode required for negotiated rates but not otherwise, for some reason
41
- xml.StateProvinceCode(location.region.code) if location.region
42
- xml.CountryCode(location.country.code) if location.country
43
- residential_address_indicator(xml, location)
44
- end
45
- end
46
-
47
- private
48
-
49
- def residential_address_indicator(xml, location)
50
- # Quote residential rates by default. If UPS doesn't know if the address is residential or
51
- # commercial, it will quote a residential rate by default. Even with this flag being set,
52
- # if UPS knows the address is commercial it will often quote a commercial rate.
53
- #
54
- xml.ResidentialAddressIndicator unless location.commercial?
55
- end
56
- end
57
- end
58
- end
59
- end
60
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeAddressValidationRequest
7
- attr_reader :location
8
-
9
- REQUEST_ACTION = 'XAV'
10
- REQUEST_OPTIONS = {
11
- validation: 1,
12
- classification: 2,
13
- both: 3
14
- }.freeze
15
-
16
- def self.call(location:)
17
- xml_builder = Nokogiri::XML::Builder.new do |xml|
18
- xml.AddressValidationRequest do
19
- xml.Request do
20
- xml.RequestAction REQUEST_ACTION
21
- xml.RequestOption REQUEST_OPTIONS[:both]
22
- end
23
-
24
- xml.AddressKeyFormat do
25
- xml.ConsigneeName(location.company_name.presence || location.name)
26
- xml.AddressLine location.address1
27
- xml.AddressLine location.address2
28
- xml.PoliticalDivision2 location.city
29
- xml.PoliticalDivision1 location.region.code
30
- xml.PostcodePrimaryLow location.zip
31
- xml.CountryCode location.country.code
32
- end
33
- end
34
- end
35
- xml_builder.to_xml
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeCityStateLookupRequest
7
- REQUEST_ACTION = 'AV'
8
-
9
- def self.call(location:)
10
- xml_builder = Nokogiri::XML::Builder.new do |xml|
11
- xml.AddressValidationRequest do
12
- xml.Request do
13
- xml.RequestAction REQUEST_ACTION
14
- end
15
- xml.Address do
16
- xml.PostalCode location.zip
17
- xml.CountryCode location.country.code
18
- end
19
- end
20
- end
21
- xml_builder.to_xml
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializePackageNode
7
- def self.call(
8
- xml:,
9
- package:,
10
- reference_numbers: {},
11
- delivery_confirmation_code: nil,
12
- shipper_release: false,
13
- transmit_dimensions: true,
14
- declared_value: false
15
- )
16
- xml.Package do
17
- xml.PackagingType do
18
- xml.Code('02')
19
- end
20
-
21
- if package.items.any?(&:description)
22
- xml.Description(package.items.map(&:description).compact.join(', '))
23
- end
24
-
25
- if transmit_dimensions && package.dimensions.all? { |dim| !dim.value.zero? && !dim.value.infinite? }
26
- xml.Dimensions do
27
- xml.UnitOfMeasurement do
28
- xml.Code('IN')
29
- end
30
- xml.Length(package.length.convert_to(:inches).value.to_f.round(3))
31
- xml.Width(package.width.convert_to(:inches).value.to_f.round(3))
32
- xml.Height(package.height.convert_to(:inches).value.to_f.round(3))
33
- end
34
- end
35
-
36
- xml.PackageWeight do
37
- xml.UnitOfMeasurement do
38
- xml.Code('LBS')
39
- end
40
-
41
- xml.Weight([package.weight.convert_to(:pounds).value.to_f.round(2).ceil, 1].max)
42
- end
43
-
44
- xml.PackageServiceOptions do
45
- if shipper_release
46
- xml.ShipperReleaseIndicator
47
- end
48
- if delivery_confirmation_code
49
- xml.DeliveryConfirmation do
50
- xml.DCISType(delivery_confirmation_code)
51
- end
52
- end
53
- if declared_value
54
- xml.DeclaredValue do
55
- xml.CurrencyCode('USD')
56
- monetary_value = package.items.inject(Money.new(0, 'USD')) do |package_sum, item|
57
- package_sum + (item.cost || Money.new(0, 'USD'))
58
- end
59
- xml.MonetaryValue(monetary_value)
60
- end
61
- end
62
- end
63
-
64
- reference_numbers.each do |reference_code, reference_number|
65
- xml.ReferenceNumber do
66
- xml.Code(reference_code)
67
- xml.Value(reference_number)
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
75
- end
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeRatingServiceSelectionRequest
7
- def self.call(shipment:, options:)
8
- shipper = options.shipper || shipment.origin
9
-
10
- xml_builder = Nokogiri::XML::Builder.new do |xml|
11
- xml.RatingServiceSelectionRequest do
12
- xml.Request do
13
- xml.RequestAction('Rate')
14
- # If no shipping method is given, request all of them
15
- # I one is given, omit the request option. It then becomes "Rate", the default.
16
- xml.RequestOption('Shop') unless options.shipping_method
17
- xml.SubVersion(options.sub_version)
18
- # Optional element to identify transactions between client and server.
19
- if options.customer_context
20
- xml.TransactionReference do
21
- xml.CustomerContext(options.customer_context)
22
- end
23
- end
24
- end
25
-
26
- xml.PickupType do
27
- xml.Code(options.pickup_type_code)
28
- end
29
- xml.CustomerClassification do
30
- xml.Code(options.customer_classification_code)
31
- end
32
-
33
- xml.Shipment do
34
- # not implemented: Shipment/Description element
35
- xml.Shipper do
36
- SerializeAddressSnippet.call(xml: xml, location: shipper)
37
-
38
- xml.ShipperNumber(options.shipper_number)
39
- end
40
-
41
- xml.ShipTo do
42
- SerializeAddressSnippet.call(xml: xml, location: shipment.destination)
43
-
44
- if options.destination_account
45
- xml.ShipperAssignedIdentificationNumber(options.destination_account)
46
- end
47
- end
48
-
49
- if shipper != shipment.origin
50
- xml.ShipFrom do
51
- SerializeAddressSnippet.call(xml: xml, location: shipment.origin)
52
- end
53
- end
54
-
55
- if options.pickup_date && options.sub_version.to_i >= 2205
56
- xml.DeliveryTimeInformation do
57
- xml.Pickup do
58
- xml.Date options.pickup_date.strftime('%Y%m%d')
59
- xml.Time options.pickup_date.strftime('%H%M')
60
- end
61
- end
62
- end
63
-
64
- shipment.packages.each do |package|
65
- package_options = options.options_for_package(package)
66
- SerializePackageNode.call(
67
- xml: xml,
68
- package: package,
69
- transmit_dimensions: package_options.transmit_dimensions
70
- )
71
- end
72
-
73
- if options.shipping_method
74
- xml.Service do
75
- xml.Code options.shipping_method.service_code
76
- end
77
- end
78
-
79
- xml.ShipmentServiceOptions do
80
- xml.UPScarbonneutralIndicator if options.carbon_neutral
81
- xml.SaturdayDelivery if options.saturday_delivery
82
- xml.SaturdayPickup if options.saturday_pickup
83
- end
84
-
85
- if options.negotiated_rates
86
- xml.RateInformation do
87
- xml.NegotiatedRatesIndicator if options.negotiated_rates
88
- end
89
- end
90
- end
91
- end
92
- end
93
- xml_builder.to_xml
94
- end
95
- end
96
- end
97
- end
98
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeShipmentAcceptRequest
7
- def self.call(digest:, options:)
8
- xml_builder = Nokogiri::XML::Builder.new do |xml|
9
- xml.ShipmentAcceptRequest do
10
- xml.Request do
11
- xml.RequestAction('ShipAccept')
12
- xml.SubVersion(options.sub_version)
13
- if options.customer_context
14
- xml.TransactionReference do
15
- xml.CustomerContext(options.customer_context)
16
- end
17
- end
18
- end
19
- xml.ShipmentDigest(digest)
20
- end
21
- end
22
- xml_builder.to_xml
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FriendlyShipping
4
- module Services
5
- class Ups
6
- class SerializeShipmentAddressSnippet < SerializeAddressSnippet
7
- class << self
8
- private
9
-
10
- def residential_address_indicator(xml, location)
11
- # Shipment creation uses a different element to indicate residential addresses.
12
- # Rates use ResidentialAddressIndicator whereas shipments use ResidentialAddress.
13
- # Presence indicates residential address. Absence indicates commercial address.
14
- #
15
- xml.ResidentialAddress unless location.commercial?
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end