Class: Edi::Walmart::FeedMessageSender
- Inherits:
-
BaseEdiService
- Object
- BaseService
- BaseEdiService
- Edi::Walmart::FeedMessageSender
- Defined in:
- app/services/edi/walmart/feed_message_sender.rb
Overview
Service object: feed message sender.
Direct Known Subclasses
InventoryMessageSender, ListingMessageFeedSender, PriceMessageSender
Constant Summary
Constants included from RequestIdentifiable
RequestIdentifiable::REQUEST_ID_HEADERS
Constants included from AddressAbbreviator
AddressAbbreviator::MAX_LENGTH
Instance Attribute Summary
Attributes inherited from BaseEdiService
Attributes inherited from BaseService
Instance Method Summary collapse
- #ecl_in_queue ⇒ Object
-
#instantiate_transporter(transporter, transporter_profile = nil, options = {}) ⇒ Transport::HttpWalmartSellerApiConnection
The transporter.
-
#process(edi_communication_logs = nil) ⇒ Object
This process is the same for any feed, but in our case we start with implementing inventory.
Methods inherited from BaseEdiService
#amazon_feed_product_type, #duplicate_po_already_notified?, #initialize, #mark_duplicate_po_as_notified, #onboard_ordered_catalog_items, #report_order_creation_issues, #safe_process_edi_communication_log
Methods included from RequestIdentifiable
Methods included from AddressAbbreviator
#abbreviate_street, #collect_street_originals, #record_address_abbreviation_notes
Methods inherited from BaseService
#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger
Constructor Details
This class inherits a constructor from Edi::BaseEdiService
Instance Method Details
#ecl_in_queue ⇒ Object
58 59 60 61 62 63 |
# File 'app/services/edi/walmart/feed_message_sender.rb', line 58 def ecl_in_queue EdiCommunicationLog.requiring_processing .where(partner: orchestrator.partner) .where(category: feed_category) .order(:created_at) end |
#instantiate_transporter(transporter, transporter_profile = nil, options = {}) ⇒ Transport::HttpWalmartSellerApiConnection
Returns the transporter.
70 71 72 73 74 75 76 77 |
# File 'app/services/edi/walmart/feed_message_sender.rb', line 70 def instantiate_transporter(transporter, transporter_profile = nil, = {}) case transporter when :http_walmart_seller_api Transport::HttpWalmartSellerApiConnection.new({ profile: transporter_profile }.merge()) else raise "Unknown transporter: #{transporter}" end end |
#process(edi_communication_logs = nil) ⇒ Object
This process is the same for any feed, but in our case we start with implementing inventory
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 |
# File 'app/services/edi/walmart/feed_message_sender.rb', line 10 def process(edi_communication_logs = nil) feed_transport = instantiate_transporter(orchestrator.transporter, orchestrator.transporter_profile) edi_communication_logs ||= ecl_in_queue [edi_communication_logs].flatten.each do |ecl| logger.info "Sending feed data to #{orchestrator.partner}" query_char = (query_param.present? ? '&' : '') query_str = "?#{query_param}#{query_char}feedType=#{feed_type}" # Every Walmart feed type (inventory, PRICE_AND_PROMOTION, …) is sent as a raw # JSON request body. #1756 switched inventory to a multipart `file` upload with # an `application/octet-stream` part and failed 100% of US+CA feeds # (ERR_EXT_DATA_0503009, itemsReceived 0) until it was reverted. Note Walmart's # own docs show inventory as a multipart JSON file upload, so if multipart is # revisited the part must be `application/json` — do not retry octet-stream. res = feed_transport.send_data(ecl.data, "#{orchestrator.}#{query_str}", 'POST') # Read the response body once (HTTP::Response::Body can only be consumed once) response_body = res[:http_result]&.body.to_s # Persisted, not just logged: FeedSubmissionResultProcessor overwrites #notes # with the async poll result, so the submission's correlation id — the handle # Walmart Seller Support traces a feed by — has to survive outside notes. ecl.file_info = ecl.file_info.to_h.merge('wm_correlation_id' => res[:correlation_id], 'submitted_at' => Time.current.utc.iso8601) ecl.notes = "HTTP CODE: #{res[:http_result]&.status}, HTTP BODY: #{response_body}, HTTP METHOD: 'POST', WM_QOS.CORRELATION_ID: #{res[:correlation_id]}, Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}" logger.info "Result: HTTP CODE: #{res[:http_result]&.status}, HTTP BODY: #{response_body}" if res[:success] && response_body.present? json_hash = JSON.parse(response_body).with_indifferent_access res_feed_id = json_hash[:feedId] feed_status = json_hash[:feedStatus] # Check for ingestion errors even if HTTP status is 200 if feed_status == 'ERROR' || json_hash[:ingestionErrors].present? ingestion_errors = json_hash.dig(:ingestionErrors, :ingestionError) || [] = ingestion_errors.map { |e| "#{e[:code]}: #{e[:description]}" }.join('; ') logger.error "[Walmart FeedSender] Feed submission returned ERROR status: #{}" ecl.notes = "#{ecl.notes}\nFEED STATUS: #{feed_status}, ERRORS: #{}" ecl.error else ecl.transaction_id = res_feed_id ecl.transmit_datetime = Time.current ecl.start_process! logger.info "[Walmart FeedSender] Feed submitted successfully, feedId: #{res_feed_id}, status: #{feed_status}" end else ecl.error end end edi_communication_logs end |