friendly_shipping 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.env.template +1 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +13 -4
  5. data/Gemfile +1 -0
  6. data/README.md +21 -2
  7. data/friendly_shipping.gemspec +1 -1
  8. data/lib/friendly_shipping/api_failure.rb +3 -0
  9. data/lib/friendly_shipping/api_result.rb +3 -0
  10. data/lib/friendly_shipping/carrier.rb +6 -0
  11. data/lib/friendly_shipping/http_client.rb +1 -0
  12. data/lib/friendly_shipping/item_options.rb +11 -0
  13. data/lib/friendly_shipping/label.rb +17 -9
  14. data/lib/friendly_shipping/package_options.rb +28 -0
  15. data/lib/friendly_shipping/rate.rb +9 -8
  16. data/lib/friendly_shipping/request.rb +4 -0
  17. data/lib/friendly_shipping/response.rb +3 -0
  18. data/lib/friendly_shipping/services/ship_engine.rb +10 -11
  19. data/lib/friendly_shipping/services/ship_engine/label_options.rb +34 -0
  20. data/lib/friendly_shipping/services/ship_engine/label_package_options.rb +28 -0
  21. data/lib/friendly_shipping/services/ship_engine/parse_label_response.rb +6 -1
  22. data/lib/friendly_shipping/services/ship_engine/parse_rate_estimate_response.rb +7 -7
  23. data/lib/friendly_shipping/services/ship_engine/rate_estimates_options.rb +25 -0
  24. data/lib/friendly_shipping/services/ship_engine/serialize_label_shipment.rb +15 -14
  25. data/lib/friendly_shipping/services/ship_engine/serialize_rate_estimate_request.rb +2 -2
  26. data/lib/friendly_shipping/services/ups.rb +47 -2
  27. data/lib/friendly_shipping/services/ups/label_billing_options.rb +41 -0
  28. data/lib/friendly_shipping/services/ups/label_item_options.rb +74 -0
  29. data/lib/friendly_shipping/services/ups/label_options.rb +165 -0
  30. data/lib/friendly_shipping/services/ups/label_package_options.rb +43 -0
  31. data/lib/friendly_shipping/services/ups/parse_money_element.rb +128 -0
  32. data/lib/friendly_shipping/services/ups/parse_rate_response.rb +8 -7
  33. data/lib/friendly_shipping/services/ups/parse_shipment_accept_response.rb +75 -0
  34. data/lib/friendly_shipping/services/ups/parse_shipment_confirm_response.rb +22 -0
  35. data/lib/friendly_shipping/services/ups/parse_xml_response.rb +2 -1
  36. data/lib/friendly_shipping/services/ups/serialize_address_snippet.rb +11 -6
  37. data/lib/friendly_shipping/services/ups/serialize_package_node.rb +21 -6
  38. data/lib/friendly_shipping/services/ups/serialize_shipment_accept_request.rb +27 -0
  39. data/lib/friendly_shipping/services/ups/serialize_shipment_address_snippet.rb +21 -0
  40. data/lib/friendly_shipping/services/ups/serialize_shipment_confirm_request.rb +282 -0
  41. data/lib/friendly_shipping/services/ups_freight.rb +76 -0
  42. data/lib/friendly_shipping/services/ups_freight/generate_commodity_information.rb +33 -0
  43. data/lib/friendly_shipping/services/ups_freight/generate_freight_rate_request_hash.rb +72 -0
  44. data/lib/friendly_shipping/services/ups_freight/generate_location_hash.rb +39 -0
  45. data/lib/friendly_shipping/services/ups_freight/generate_ups_security_hash.rb +23 -0
  46. data/lib/friendly_shipping/services/ups_freight/parse_freight_rate_response.rb +53 -0
  47. data/lib/friendly_shipping/services/ups_freight/parse_json_response.rb +38 -0
  48. data/lib/friendly_shipping/services/ups_freight/rates_item_options.rb +72 -0
  49. data/lib/friendly_shipping/services/ups_freight/rates_options.rb +54 -0
  50. data/lib/friendly_shipping/services/ups_freight/rates_package_options.rb +38 -0
  51. data/lib/friendly_shipping/services/ups_freight/shipping_methods.rb +25 -0
  52. data/lib/friendly_shipping/services/usps.rb +1 -1
  53. data/lib/friendly_shipping/services/usps/parse_xml_response.rb +1 -1
  54. data/lib/friendly_shipping/services/usps/serialize_rate_request.rb +0 -4
  55. data/lib/friendly_shipping/shipment_options.rb +23 -0
  56. data/lib/friendly_shipping/shipping_method.rb +7 -0
  57. data/lib/friendly_shipping/version.rb +1 -1
  58. metadata +33 -6
@@ -19,6 +19,10 @@ module FriendlyShipping
19
19
  label_url = label_uri_string
20
20
  end
21
21
 
22
+ currency = parsed_json.dig('shipment_cost', 'currency')
23
+ cents = parsed_json.dig('shipment_cost', 'amount') * 100
24
+ shipment_cost = Money.new(cents, currency)
25
+
22
26
  label = FriendlyShipping::Label.new(
23
27
  id: parsed_json['label_id'],
24
28
  shipment_id: parsed_json['shipment_id'],
@@ -27,7 +31,8 @@ module FriendlyShipping
27
31
  label_href: label_url,
28
32
  label_data: label_data,
29
33
  label_format: parsed_json['label_format'].to_sym,
30
- shipment_cost: parsed_json['shipment_cost']['amount'],
34
+ shipment_cost: shipment_cost,
35
+ cost: shipment_cost,
31
36
  data: parsed_json
32
37
  )
33
38
 
@@ -10,14 +10,16 @@ module FriendlyShipping
10
10
  extend Dry::Monads::Result::Mixin
11
11
 
12
12
  class << self
13
- def call(response:, carriers:, request:)
13
+ def call(response:, request:, options:)
14
14
  parsed_json = JSON.parse(response.body)
15
15
  rates = parsed_json.map do |rate|
16
- carrier = carriers.detect { |c| c.id == rate['carrier_id'] }
16
+ carrier = options.carriers.detect { |c| c.id == rate['carrier_id'] }
17
17
  next unless carrier
18
18
 
19
- shipping_method = carrier.shipping_methods.detect { |sm| sm.service_code == rate['service_code'] }
20
- next unless shipping_method
19
+ shipping_method = FriendlyShipping::ShippingMethod.new(
20
+ carrier: carrier,
21
+ service_code: rate['service_code']
22
+ )
21
23
 
22
24
  amounts = get_amounts(rate)
23
25
  FriendlyShipping::Rate.new(
@@ -26,9 +28,7 @@ module FriendlyShipping
26
28
  remote_service_id: rate['rate_id'],
27
29
  delivery_date: Time.parse(rate['estimated_delivery_date']),
28
30
  warnings: rate['warning_messages'],
29
- errors: rate['error_messages'],
30
- original_request: request,
31
- original_response: response
31
+ errors: rate['error_messages']
32
32
  )
33
33
  end.compact
34
34
 
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'friendly_shipping/shipment_options'
4
+
5
+ module FriendlyShipping
6
+ module Services
7
+ class ShipEngine
8
+ # options for the rate estimates call
9
+ #
10
+ # @attribute carriers [Array<FriendlyShipping::Carrier] a list of the carriers we want to get IDs from.
11
+ class RateEstimatesOptions < ShipmentOptions
12
+ attr_reader :carriers
13
+
14
+ def initialize(carriers:, **kwargs)
15
+ @carriers = carriers
16
+ super kwargs
17
+ end
18
+
19
+ def carrier_ids
20
+ carriers.map(&:id)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -5,20 +5,20 @@ module FriendlyShipping
5
5
  class ShipEngine
6
6
  class SerializeLabelShipment
7
7
  class << self
8
- def call(shipment:, shipping_method:, test:)
8
+ def call(shipment:, options:, test:)
9
9
  shipment_hash = {
10
- label_format: shipment.options[:label_format].presence || "pdf",
11
- label_download_type: shipment.options[:label_download_type].presence || "url",
10
+ label_format: options.label_format,
11
+ label_download_type: options.label_download_type,
12
12
  shipment: {
13
- service_code: shipping_method.service_code,
13
+ service_code: options.shipping_method.service_code,
14
14
  ship_to: serialize_address(shipment.destination),
15
15
  ship_from: serialize_address(shipment.origin),
16
- packages: serialize_packages(shipment.packages)
16
+ packages: serialize_packages(shipment.packages, options)
17
17
  }
18
18
  }
19
19
  # A carrier might not be necessary if the service code is unique within ShipEngine.
20
- if shipping_method.carrier
21
- shipment_hash[:shipment][:carrier_id] = shipping_method.carrier.id
20
+ if options.shipping_method.carrier
21
+ shipment_hash[:shipment][:carrier_id] = options.shipping_method.carrier.id
22
22
  end
23
23
 
24
24
  if test
@@ -45,15 +45,16 @@ module FriendlyShipping
45
45
  }
46
46
  end
47
47
 
48
- def serialize_packages(packages)
48
+ def serialize_packages(packages, options)
49
49
  packages.map do |package|
50
+ package_options = options.options_for_package(package)
50
51
  package_hash = serialize_weight(package.weight)
51
- if package.container.properties[:usps_label_messages]
52
- package_hash[:label_messages] = package.container.properties[:usps_label_messages]
53
- end
54
- package_code = package.container.properties[:usps_package_code]
55
- if package_code
56
- package_hash[:package_code] = package_code
52
+ package_hash[:label_messages] = package_options.messages.map.with_index do |message, index|
53
+ ["reference#{index + 1}".to_sym, message]
54
+ end.to_h
55
+
56
+ if package_options.package_code
57
+ package_hash[:package_code] = package_options.package_code
57
58
  else
58
59
  package_hash[:dimensions] = {
59
60
  unit: 'inch',
@@ -4,9 +4,9 @@ module FriendlyShipping
4
4
  module Services
5
5
  class ShipEngine
6
6
  class SerializeRateEstimateRequest
7
- def self.call(shipment:, carriers:)
7
+ def self.call(shipment:, options:)
8
8
  {
9
- carrier_ids: carriers.map(&:id),
9
+ carrier_ids: options.carrier_ids,
10
10
  from_country_code: shipment.origin.country.alpha_2_code,
11
11
  from_postal_code: shipment.origin.zip,
12
12
  to_country_code: shipment.destination.country.alpha_2_code,
@@ -6,11 +6,16 @@ require 'friendly_shipping/services/ups/serialize_access_request'
6
6
  require 'friendly_shipping/services/ups/serialize_city_state_lookup_request'
7
7
  require 'friendly_shipping/services/ups/serialize_address_validation_request'
8
8
  require 'friendly_shipping/services/ups/serialize_rating_service_selection_request'
9
- require 'friendly_shipping/services/ups/parse_address_classification_response'
9
+ require 'friendly_shipping/services/ups/serialize_shipment_accept_request'
10
+ require 'friendly_shipping/services/ups/serialize_shipment_confirm_request'
10
11
  require 'friendly_shipping/services/ups/parse_address_validation_response'
12
+ require 'friendly_shipping/services/ups/parse_address_classification_response'
11
13
  require 'friendly_shipping/services/ups/parse_city_state_lookup_response'
12
14
  require 'friendly_shipping/services/ups/parse_rate_response'
15
+ require 'friendly_shipping/services/ups/parse_shipment_confirm_response'
16
+ require 'friendly_shipping/services/ups/parse_shipment_accept_response'
13
17
  require 'friendly_shipping/services/ups/shipping_methods'
18
+ require 'friendly_shipping/services/ups/label_options'
14
19
 
15
20
  module FriendlyShipping
16
21
  module Services
@@ -32,7 +37,9 @@ module FriendlyShipping
32
37
  RESOURCES = {
33
38
  address_validation: '/ups.app/xml/XAV',
34
39
  city_state_lookup: '/ups.app/xml/AV',
35
- rates: '/ups.app/xml/Rate'
40
+ rates: '/ups.app/xml/Rate',
41
+ ship_confirm: '/ups.app/xml/ShipConfirm',
42
+ ship_accept: '/ups.app/xml/ShipAccept',
36
43
  }.freeze
37
44
 
38
45
  def initialize(key:, login:, password:, test: true, client: HttpClient.new)
@@ -65,6 +72,44 @@ module FriendlyShipping
65
72
  end
66
73
  end
67
74
 
75
+ def labels(shipment, options:, debug: false)
76
+ ## Method body starts
77
+ ship_confirm_request_xml = SerializeShipmentConfirmRequest.call(
78
+ shipment: shipment,
79
+ options: options
80
+ )
81
+ ship_confirm_url = base_url + RESOURCES[:ship_confirm]
82
+
83
+ ship_confirm_request = FriendlyShipping::Request.new(
84
+ url: ship_confirm_url,
85
+ body: access_request_xml + ship_confirm_request_xml,
86
+ debug: debug
87
+ )
88
+
89
+ client.post(ship_confirm_request).bind do |ship_confirm_response|
90
+ ParseShipmentConfirmResponse.call(
91
+ request: ship_confirm_request,
92
+ response: ship_confirm_response
93
+ )
94
+ end.bind do |ship_confirm_result|
95
+ ship_accept_url = base_url + RESOURCES[:ship_accept]
96
+ ship_accept_request_xml = SerializeShipmentAcceptRequest.call(
97
+ digest: ship_confirm_result.data,
98
+ options: options
99
+ )
100
+
101
+ ship_accept_request = FriendlyShipping::Request.new(
102
+ url: ship_accept_url,
103
+ body: access_request_xml + ship_accept_request_xml,
104
+ debug: debug
105
+ )
106
+
107
+ client.post(ship_accept_request).bind do |ship_accept_response|
108
+ ParseShipmentAcceptResponse.call(request: ship_accept_request, response: ship_accept_response)
109
+ end
110
+ end
111
+ end
112
+
68
113
  # Validate an address.
69
114
  # @param [Physical::Location] location The address we want to verify
70
115
  # @return [Result<ApiResult<Array<Physical::Location>>>] The response data from UPS encoded in a
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FriendlyShipping
4
+ module Services
5
+ class Ups
6
+ # Represents billing-related options for obtaining shipment labels.
7
+ # @option bill_third_party [Boolean] When truthy, bill an account other than the shipper's.
8
+ # Specified by billing_(account, zip and country)
9
+ # @option bill_to_consignee [Boolean] If billing a third party, bill the consignee instead of the 3rd party shipper
10
+ # @option prepay [Boolean] If truthy the shipper will be bill immediately. Otherwise the shipper is billed
11
+ # when the label is used. Default: false
12
+ class LabelBillingOptions
13
+ attr_reader :bill_third_party,
14
+ :bill_to_consignee,
15
+ :prepay,
16
+ :billing_account,
17
+ :billing_zip,
18
+ :billing_country,
19
+ :currency
20
+
21
+ def initialize(
22
+ bill_third_party: false,
23
+ bill_to_consignee: false,
24
+ prepay: false,
25
+ billing_account: nil,
26
+ billing_zip: nil,
27
+ billing_country: nil,
28
+ currency: nil
29
+ )
30
+ @bill_third_party = bill_third_party
31
+ @bill_to_consignee = bill_to_consignee
32
+ @prepay = prepay
33
+ @billing_account = billing_account
34
+ @billing_zip = billing_zip
35
+ @billing_country = billing_country
36
+ @currency = currency
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'friendly_shipping/item_options'
4
+
5
+ module FriendlyShipping
6
+ module Services
7
+ class Ups
8
+ class LabelItemOptions < FriendlyShipping::ItemOptions
9
+ PRODUCT_UNIT_OF_MEASURE_CODES = {
10
+ barrel: 'BA',
11
+ bundle: 'BE',
12
+ bag: 'BG',
13
+ bunch: 'BH',
14
+ box: 'BOX',
15
+ bolt: 'BT',
16
+ butt: 'BU',
17
+ canister: 'CI',
18
+ centimeter: 'CM',
19
+ container: 'CON',
20
+ crate: 'CR',
21
+ case: 'CS',
22
+ carton: 'CT',
23
+ cylinder: 'CY',
24
+ dozen: 'DOZ',
25
+ each: 'EA',
26
+ envelope: 'EN',
27
+ feet: 'FT',
28
+ kilogram: 'KG',
29
+ kilograms: 'KGS',
30
+ pound: 'LB',
31
+ pounds: 'LBS',
32
+ liter: 'L',
33
+ meter: 'M',
34
+ number: 'NMB',
35
+ packet: 'PA',
36
+ pallet: 'PAL',
37
+ piece: 'PC',
38
+ pieces: 'PCS',
39
+ proof_liters: 'PF',
40
+ package: 'PKG',
41
+ pair: 'PR',
42
+ pairs: 'PRS',
43
+ roll: 'RL',
44
+ set: 'SET',
45
+ square_meters: 'SME',
46
+ square_yards: 'SYD',
47
+ tube: 'TU',
48
+ yard: 'YD',
49
+ other: 'OTH'
50
+ }.freeze
51
+
52
+ attr_reader :commodity_code
53
+
54
+ def initialize(
55
+ commodity_code: nil,
56
+ product_unit_of_measure: :number,
57
+ **kwargs
58
+ )
59
+ @commodity_code = commodity_code
60
+ @product_unit_of_measure = product_unit_of_measure
61
+ super kwargs
62
+ end
63
+
64
+ def product_unit_of_measure_code
65
+ PRODUCT_UNIT_OF_MEASURE_CODES[product_unit_of_measure]
66
+ end
67
+
68
+ private
69
+
70
+ attr_reader :product_unit_of_measure
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'friendly_shipping/services/ups/label_package_options'
4
+ require 'friendly_shipping/services/ups/label_billing_options'
5
+
6
+ module FriendlyShipping
7
+ module Services
8
+ # Option container for a generating UPS labels for a shipment
9
+ #
10
+ # Required:
11
+ #
12
+ # @param shipping_method [FriendlyShipping::ShippingMethod] The shipping method to use. We only need the
13
+ # service_code to be set.
14
+ # @param shipper_number [String] account number for the shipper
15
+ #
16
+ # Optional:
17
+ #
18
+ # @param shipper [Physical::Location] The company sending the shipment. Defaults to the shipment's origin.
19
+ # @param customer_context [String ] Optional element to identify transactions between client and server
20
+ # @param validate_address [Boolean] Validate the city field with ZIP code and state. If false, only ZIP code
21
+ # and state are validated. Default: true
22
+ # @param negotiated_rates [Boolean] if truthy negotiated rates will be requested from ups. Only valid if
23
+ # shipper account has negotiated rates. Default: false
24
+ # @option sold_to [Physical::Location] The person or company who imports and pays any duties due on the
25
+ # current shipment. Default: The shipment's destination
26
+ # @option saturday_delivery [Boolean] should we request Saturday delivery?. Default: false
27
+ # @option label_format [String] GIF, EPL, ZPL, STARPL and SPL
28
+ # @option label_size [Array<Integer>] Dimensions of the label. Default: [4, 6]
29
+ # @option delivery_confirmation [Symbol] Can be set to any key from SHIPMENT_DELIVERY_CONFIRMATION_CODES.
30
+ # Only possible for international shipments that are not between the US and Puerto Rico.
31
+ # @option carbon_neutral [Boolean] Ship with UPS' carbon neutral program
32
+ # @option return_service_code [Symbol] If present, marks this a return label. The kind
33
+ # of return label is specified by the symbol, one of the keys in RETURN_SERVICE_CODES. Default: nil
34
+ #
35
+ # Shipment options for international shipping:
36
+ #
37
+ # @option paperless_invoice [Boolean] set to truthy if using paperless invoice to ship internationally. Default false
38
+ # @option terms_of_shipment [Symbol] used with paperless invoice to specify who pays duties and taxes.
39
+ # See TERMS_OF_SHIPMENT constant for possible options.
40
+ # @option reason_for_export [String] A reason to export the current shipment. Possible values: 'SALE', 'GIFT', 'SAMPLE',
41
+ # 'RETURN', 'REPAIR', 'INTERCOMPANYDATA', Any other reason. Default: 'SALE'.
42
+ # @option invoice_date [Date] The invoice date for the shipment
43
+ #
44
+ class Ups
45
+ class LabelOptions < FriendlyShipping::ShipmentOptions
46
+ SHIPMENT_DELIVERY_CONFIRMATION_CODES = {
47
+ delivery_confirmation_signature_required: 1,
48
+ delivery_confirmation_adult_signature_required: 2
49
+ }.freeze
50
+
51
+ TERMS_OF_SHIPMENT_CODES = {
52
+ cost_and_freight: 'CFR',
53
+ cost_insurance_and_freight: 'CIF',
54
+ carriage_and_insurance_paid: 'CIP',
55
+ carriage_paid_to: 'CPT',
56
+ delivered_at_frontier: 'DAF',
57
+ delivery_duty_paid: 'DDP',
58
+ delivery_duty_unpaid: 'DDU',
59
+ delivered_ex_quay: 'DEQ',
60
+ delivered_ex_ship: 'DES',
61
+ ex_works: 'EXW',
62
+ free_alongside_ship: 'FAS',
63
+ free_carrier: 'FCA',
64
+ free_on_board: 'FOB'
65
+ }.freeze
66
+
67
+ RETURN_SERVICE_CODES = {
68
+ ups_print_and_mail: 2, # UPS Print and Mail (PNM)
69
+ ups_return_1_attempt: 3, # UPS Return Service 1-Attempt
70
+ ups_return_3_attempt: 5, # UPS Return Service 3-Attempt (RS3)
71
+ ups_electronic_return_label: 8, # UPS Electronic Return Label (ERL)
72
+ ups_print_return_label: 9, # UPS Print Return Label (PRL)
73
+ ups_exchange_print_return: 10, # UPS Exchange Print Return Label
74
+ ups_pack_collect_1_attemt_box_1: 11, # UPS Pack & Collect Service 1-Attempt Box 1
75
+ ups_pack_collect_1_attemt_box_2: 12, # UPS Pack & Collect Service 1-Attempt Box 2
76
+ ups_pack_collect_1_attemt_box_3: 13, # UPS Pack & Collect Service 1-Attempt Box 3
77
+ ups_pack_collect_1_attemt_box_4: 14, # UPS Pack & Collect Service 1-Attempt Box 4
78
+ ups_pack_collect_1_attemt_box_5: 15, # UPS Pack & Collect Service 1-Attempt Box 5
79
+ ups_pack_collect_3_attemt_box_1: 16, # UPS Pack & Collect Service 1-Attempt Box 1
80
+ ups_pack_collect_3_attemt_box_2: 17, # UPS Pack & Collect Service 1-Attempt Box 2
81
+ ups_pack_collect_3_attemt_box_3: 18, # UPS Pack & Collect Service 1-Attempt Box 3
82
+ ups_pack_collect_3_attemt_box_4: 19, # UPS Pack & Collect Service 1-Attempt Box 4
83
+ ups_pack_collect_3_attemt_box_5: 20 # UPS Pack & Collect Service 1-Attempt Box 5
84
+ }.freeze
85
+
86
+ attr_reader :shipping_method,
87
+ :shipper_number,
88
+ :shipper,
89
+ :customer_context,
90
+ :validate_address,
91
+ :negotiated_rates,
92
+ :billing_options,
93
+ :sold_to,
94
+ :saturday_delivery,
95
+ :label_format,
96
+ :label_size,
97
+ :carbon_neutral,
98
+ :paperless_invoice,
99
+ :reason_for_export,
100
+ :invoice_date
101
+
102
+ def initialize(
103
+ shipping_method:,
104
+ shipper_number:,
105
+ shipper: nil,
106
+ customer_context: nil,
107
+ validate_address: true,
108
+ negotiated_rates: false,
109
+ billing_options: LabelBillingOptions.new,
110
+ sold_to: nil,
111
+ saturday_delivery: false,
112
+ label_format: 'GIF',
113
+ label_size: [4, 6],
114
+ delivery_confirmation: nil,
115
+ carbon_neutral: true,
116
+ return_service: nil,
117
+ paperless_invoice: false,
118
+ terms_of_shipment: nil,
119
+ reason_for_export: 'SALE',
120
+ invoice_date: nil,
121
+ package_options_class: LabelPackageOptions,
122
+ **kwargs
123
+ )
124
+ @shipping_method = shipping_method
125
+ @shipper_number = shipper_number
126
+ @shipper = shipper
127
+ @customer_context = customer_context
128
+ @validate_address = validate_address
129
+ @negotiated_rates = negotiated_rates
130
+ @billing_options = billing_options
131
+ @sold_to = sold_to
132
+ @saturday_delivery = saturday_delivery
133
+ @label_format = label_format
134
+ @label_size = label_size
135
+ @delivery_confirmation = delivery_confirmation
136
+ @carbon_neutral = carbon_neutral
137
+ @return_service = return_service
138
+ @paperless_invoice = paperless_invoice
139
+ @terms_of_shipment = terms_of_shipment
140
+ @reason_for_export = reason_for_export
141
+ @invoice_date = invoice_date
142
+ super kwargs.merge(package_options_class: package_options_class)
143
+ end
144
+
145
+ def delivery_confirmation_code
146
+ SHIPMENT_DELIVERY_CONFIRMATION_CODES[delivery_confirmation]
147
+ end
148
+
149
+ def terms_of_shipment_code
150
+ TERMS_OF_SHIPMENT_CODES[terms_of_shipment]
151
+ end
152
+
153
+ def return_service_code
154
+ RETURN_SERVICE_CODES[return_service]
155
+ end
156
+
157
+ private
158
+
159
+ attr_reader :terms_of_shipment,
160
+ :return_service,
161
+ :delivery_confirmation
162
+ end
163
+ end
164
+ end
165
+ end