Class: Shipping::WalmartSeller
- Defined in:
- app/services/shipping/walmart_seller.rb
Overview
Shipping carrier class for Walmart's "Ship with Walmart" (SWW) service
Provides discounted shipping labels for Walmart marketplace orders
This class follows the same interface as other Shipping::* carriers
and integrates with the WyShipping rate comparison system.
Usage:
shipper = Shipping::WalmartSeller.new(
walmart_partner: :walmart_seller_us,
purchase_order_id: '1234567890',
sender_address: '123 Warehouse St',
# ... other address fields
)
response = shipper.find_rates
if response[:success]
response[:rates].each { |rate| puts rate[:service_name] }
end
Constant Summary collapse
- CARRIER_NAME =
'WalmartSeller'- SERVICE_CODE_PREFIX =
Service code prefix to distinguish SWW rates from direct carrier rates
'SWW_'
Instance Attribute Summary collapse
-
#api_log ⇒ Object
readonly
Accumulated API call log from all SWW operations on this shipper instance.
-
#deliver_by_date ⇒ Object
Returns the value of attribute deliver_by_date.
-
#purchase_order_id ⇒ Object
Returns the value of attribute purchase_order_id.
-
#ship_by_date ⇒ Object
Returns the value of attribute ship_by_date.
-
#walmart_partner ⇒ Object
Returns the value of attribute walmart_partner.
Attributes inherited from Base
#address, #address2, #address3, #address_residential, #attention_name, #billing_account, #billing_country, #billing_zip, #ci_comments, #city, #close_report_only, #cod_amount, #cod_collection_type, #company, #country, #currency_code, #data, #debug, #declared_value, #delivery_instructions, #delivery_total_value, #description, #discount_price, #dropoff_type, #email, #eta, #export_reason, #freight_class, #freightquote_authorization_url, #freightquote_client_id, #freightquote_client_secret, #freightquote_customer_code, #freightquote_events_url, #freightquote_rating_url, #freightquote_shipping_url, #freightquote_voiding_url, #handling_instructions, #has_loading_dock, #image_type, #include_first_class_mail_options, #insured_value, #is_construction_site, #is_trade_show, #label_type, #limited_access, #line_items, #master_tracking_number, #measure_height, #measure_length, #measure_units, #measure_width, #media_mail, #multiple_piece_shipping, #negotiated_rates, #package, #package_count, #package_sequence_number, #package_total, #packages, #packaging_type, #pay_type, #phone, #pickup_datetime, #pickup_instructions, #plain_response, #price, #rate_data, #reference_number_1, #reference_number_2, #reference_number_3, #reference_number_code_1, #reference_number_code_2, #required, #requires_appointment, #requires_inside_delivery, #requires_liftgate, #response, #return_to_address, #return_to_address2, #return_to_address3, #return_to_address_residential, #return_to_attention_name, #return_to_city, #return_to_company, #return_to_country, #return_to_email, #return_to_has_loading_dock, #return_to_is_construction_site, #return_to_is_trade_show, #return_to_limited_access, #return_to_name, #return_to_phone, #return_to_requires_appointment, #return_to_requires_inside_delivery, #return_to_requires_liftgate, #return_to_state, #return_to_zip, #rl_carriers_api_key, #rl_carriers_shipping_url, #saturday_delivery, #sender_address, #sender_address2, #sender_address3, #sender_address_residential, #sender_attention_name, #sender_city, #sender_company, #sender_country, #sender_email, #sender_has_loading_dock, #sender_is_construction_site, #sender_is_trade_show, #sender_limited_access, #sender_name, #sender_phone, #sender_requires_appointment, #sender_requires_inside_delivery, #sender_requires_liftgate, #sender_state, #sender_tax_identification_number, #sender_zip, #service_code, #service_type, #services, #ship_date, #shipengine_api_key, #shipengine_canadapost_account_id, #shipengine_canadapost_parent_account_number, #shipengine_canpar_account_id, #shipengine_dhl_express_account_id, #shipengine_fed_ex_account_id, #shipengine_fed_ex_ca_account_id, #shipengine_purolator_account_id, #shipengine_ups_account_id, #shipengine_ups_ca_account_id, #shipengine_usps_account_id, #shipper_address, #shipper_address2, #shipper_address3, #shipper_address_residential, #shipper_attention_name, #shipper_city, #shipper_company, #shipper_country, #shipper_email, #shipper_has_loading_dock, #shipper_is_construction_site, #shipper_is_trade_show, #shipper_limited_access, #shipper_name, #shipper_phone, #shipper_requires_appointment, #shipper_requires_inside_delivery, #shipper_requires_liftgate, #shipper_state, #shipper_zip, #signature_confirmation, #skip_png_download, #skip_rate_test, #special_instructions, #state, #tax_identification_number, #time_in_transit, #total_shipment_weight, #transaction_type, #weight, #weight_units, #zip
Instance Method Summary collapse
-
#create_label(rate, logger = nil) ⇒ Hash
Create a shipping label via Ship with Walmart.
-
#download_label(carrier, tracking_number, logger = nil) ⇒ Hash
Download a shipping label PDF Per Walmart API, labels are downloaded using carrier + tracking number.
-
#find_rates(logger = nil) ⇒ Hash
Get shipping rate estimates from Ship with Walmart.
-
#get_labels_by_po(purchase_order_id = nil, logger = nil) ⇒ Hash
Get all labels for a purchase order Useful for finding labels when you only have the PO number.
-
#initialize(options = {}) ⇒ WalmartSeller
constructor
A new instance of WalmartSeller.
-
#void_label(carrier, tracking_number, logger = nil) ⇒ Hash
Void/discard a shipping label Per Walmart API, labels are voided using carrier + tracking number.
Methods inherited from Base
#fedex, #purolator, state_from_zip, #ups, #ups_freight
Constructor Details
#initialize(options = {}) ⇒ WalmartSeller
Returns a new instance of WalmartSeller.
32 33 34 35 36 37 38 39 |
# File 'app/services/shipping/walmart_seller.rb', line 32 def initialize( = {}) super @walmart_partner = [:walmart_partner] @purchase_order_id = [:purchase_order_id] @deliver_by_date = [:deliver_by_date] @ship_by_date = [:ship_by_date] @api_log = [] end |
Instance Attribute Details
#api_log ⇒ Object (readonly)
Accumulated API call log from all SWW operations on this shipper instance
30 31 32 |
# File 'app/services/shipping/walmart_seller.rb', line 30 def api_log @api_log end |
#deliver_by_date ⇒ Object
Returns the value of attribute deliver_by_date.
22 23 24 |
# File 'app/services/shipping/walmart_seller.rb', line 22 def deliver_by_date @deliver_by_date end |
#purchase_order_id ⇒ Object
Returns the value of attribute purchase_order_id.
22 23 24 |
# File 'app/services/shipping/walmart_seller.rb', line 22 def purchase_order_id @purchase_order_id end |
#ship_by_date ⇒ Object
Returns the value of attribute ship_by_date.
22 23 24 |
# File 'app/services/shipping/walmart_seller.rb', line 22 def ship_by_date @ship_by_date end |
#walmart_partner ⇒ Object
Returns the value of attribute walmart_partner.
22 23 24 |
# File 'app/services/shipping/walmart_seller.rb', line 22 def walmart_partner @walmart_partner end |
Instance Method Details
#create_label(rate, logger = nil) ⇒ Hash
Create a shipping label via Ship with Walmart
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/services/shipping/walmart_seller.rb', line 80 def create_label(rate, logger = nil) logger ||= Rails.logger return { success: false, error: 'Walmart partner and purchase order ID are required' } unless @walmart_partner.present? && @purchase_order_id.present? begin orchestrator = Edi::Walmart::Orchestrator.new(@walmart_partner) sww_client = Edi::Walmart::ShipWithWalmart.new(orchestrator) = (rate) logger.info("[SWW] Creating label for PO: #{@purchase_order_id}, carrier: #{rate[:carrier_id]}") result = sww_client.create_label() @api_log.concat(sww_client.api_log) if result.success { success: true, label_id: result.label_id, tracking_number: result.tracking_number, carrier: result.carrier, service_type: result.service_type, error: nil } else { success: false, error: result.error } end rescue StandardError => e logger.error("[SWW] create_label error: #{e.}") { success: false, error: e. } end end |
#download_label(carrier, tracking_number, logger = nil) ⇒ Hash
Download a shipping label PDF
Per Walmart API, labels are downloaded using carrier + tracking number
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'app/services/shipping/walmart_seller.rb', line 120 def download_label(carrier, tracking_number, logger = nil) logger ||= Rails.logger return { success: false, error: 'Walmart partner configuration is required' } unless @walmart_partner.present? return { success: false, error: 'Carrier and tracking number are required' } unless carrier.present? && tracking_number.present? begin orchestrator = Edi::Walmart::Orchestrator.new(@walmart_partner) sww_client = Edi::Walmart::ShipWithWalmart.new(orchestrator) result = sww_client.download_label(carrier, tracking_number) @api_log.concat(sww_client.api_log) if result.success { success: true, label_data: result.label_data, content_type: result.content_type, error: nil } else { success: false, error: result.error } end rescue StandardError => e logger.error("[SWW] download_label error: #{e.}") { success: false, error: e. } end end |
#find_rates(logger = nil) ⇒ Hash
Get shipping rate estimates from Ship with Walmart
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 72 73 74 |
# File 'app/services/shipping/walmart_seller.rb', line 43 def find_rates(logger = nil) logger ||= Rails.logger return build_error_response('Walmart partner configuration is required') unless @walmart_partner.present? return build_error_response('Valid origin and destination addresses are required') unless valid_addresses? begin orchestrator = Edi::Walmart::Orchestrator.new(@walmart_partner) sww_client = Edi::Walmart::ShipWithWalmart.new(orchestrator) = logger.info("[SWW] Requesting rates for PO: #{@purchase_order_id}") logger.info("[SWW] line_items present: #{@line_items.present?}, count: #{@line_items&.size || 0}") logger.info("[SWW] box_items from options: #{[:box_items].inspect}") logger.debug("[SWW] Rate request options: #{.inspect}") result = sww_client.get_shipping_estimates() @api_log.concat(sww_client.api_log) if result.success rates = build_rate_estimates(result.estimates) build_success_response(rates, ) else build_error_response(result.error || 'Failed to retrieve shipping estimates') end rescue StandardError => e logger.error("[SWW] find_rates error: #{e.}") logger.error(e.backtrace.first(5).join("\n")) build_error_response("Error retrieving Ship with Walmart rates: #{e.}") end end |
#get_labels_by_po(purchase_order_id = nil, logger = nil) ⇒ Hash
Get all labels for a purchase order
Useful for finding labels when you only have the PO number
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'app/services/shipping/walmart_seller.rb', line 184 def get_labels_by_po(purchase_order_id = nil, logger = nil) logger ||= Rails.logger po = purchase_order_id || @purchase_order_id return { success: false, labels: [], error: 'Walmart partner configuration is required' } unless @walmart_partner.present? return { success: false, labels: [], error: 'Purchase order ID is required' } unless po.present? begin orchestrator = Edi::Walmart::Orchestrator.new(@walmart_partner) sww_client = Edi::Walmart::ShipWithWalmart.new(orchestrator) result = sww_client.get_labels_by_purchase_order(po) @api_log.concat(sww_client.api_log) { success: result.success, labels: result.labels, error: result.error } rescue StandardError => e logger.error("[SWW] get_labels_by_po error: #{e.}") { success: false, labels: [], error: e. } end end |
#void_label(carrier, tracking_number, logger = nil) ⇒ Hash
Void/discard a shipping label
Per Walmart API, labels are voided using carrier + tracking number
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'app/services/shipping/walmart_seller.rb', line 157 def void_label(carrier, tracking_number, logger = nil) logger ||= Rails.logger return { success: false, error: 'Walmart partner configuration is required' } unless @walmart_partner.present? return { success: false, error: 'Carrier and tracking number are required' } unless carrier.present? && tracking_number.present? begin orchestrator = Edi::Walmart::Orchestrator.new(@walmart_partner) sww_client = Edi::Walmart::ShipWithWalmart.new(orchestrator) result = sww_client.discard_label(carrier, tracking_number) @api_log.concat(sww_client.api_log) { success: result.success, error: result.error } rescue StandardError => e logger.error("[SWW] void_label error: #{e.}") { success: false, error: e. } end end |