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 =
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, #importer_of_record, #include_first_class_mail_options, #insured_value, #is_construction_site, #is_trade_show, #label_type, #last_request_payload, #last_request_quote_id, #last_response_payload, #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, #paperless, #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, #response_headers, #response_status, #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.
40 41 42 43 44 45 46 47 |
# File 'app/services/shipping/walmart_seller.rb', line 40 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
32 33 34 |
# File 'app/services/shipping/walmart_seller.rb', line 32 def api_log @api_log end |
#deliver_by_date ⇒ Object
Returns the value of attribute deliver_by_date.
23 24 25 |
# File 'app/services/shipping/walmart_seller.rb', line 23 def deliver_by_date @deliver_by_date end |
#purchase_order_id ⇒ Object
Returns the value of attribute purchase_order_id.
23 24 25 |
# File 'app/services/shipping/walmart_seller.rb', line 23 def purchase_order_id @purchase_order_id end |
#ship_by_date ⇒ Object
Returns the value of attribute ship_by_date.
23 24 25 |
# File 'app/services/shipping/walmart_seller.rb', line 23 def ship_by_date @ship_by_date end |
#walmart_partner ⇒ Object
Returns the value of attribute walmart_partner.
23 24 25 |
# File 'app/services/shipping/walmart_seller.rb', line 23 def walmart_partner @walmart_partner end |
Instance Method Details
#create_label(rate, logger = nil) ⇒ Hash
Create a shipping label via Ship with Walmart
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/services/shipping/walmart_seller.rb', line 88 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
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'app/services/shipping/walmart_seller.rb', line 128 def download_label(carrier, tracking_number, logger = nil) logger ||= Rails.logger return { success: false, error: 'Walmart partner configuration is required' } if @walmart_partner.blank? 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
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'app/services/shipping/walmart_seller.rb', line 51 def find_rates(logger = nil) logger ||= Rails.logger return build_error_response('Walmart partner configuration is required') if @walmart_partner.blank? 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
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'app/services/shipping/walmart_seller.rb', line 192 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' } if @walmart_partner.blank? return { success: false, labels: [], error: 'Purchase order ID is required' } if po.blank? 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
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'app/services/shipping/walmart_seller.rb', line 165 def void_label(carrier, tracking_number, logger = nil) logger ||= Rails.logger return { success: false, error: 'Walmart partner configuration is required' } if @walmart_partner.blank? 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 |