Module: Models::CatalogItemWalmartHelper

Extended by:
ActiveSupport::Concern
Included in:
CatalogItem
Defined in:
app/concerns/models/catalog_item_walmart_helper.rb

Overview

ActiveSupport::Concern mixin: catalog item walmart helper.

Constant Summary collapse

WALMART_ALREADY_RETIRED_ERROR_CODE =

Walmart returns HTTP 404 with this error code when the SKU has no live
offer in their catalog — i.e. it was already retired (or never existed).
We treat that as success so the discontinue flow doesn't loop forever.

'CONTENT_NOT_FOUND.GMP_RECEIVER_API'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.walmartsActiveRecord::Relation<Models::CatalogItemWalmartHelper>

A relation of Models::CatalogItemWalmartHelpers that are walmarts. Active Record Scope

Returns:

See Also:



15
# File 'app/concerns/models/catalog_item_walmart_helper.rb', line 15

scope :walmarts, -> { where(catalog_id: CatalogConstants::WALMART_CATALOGS) }

Instance Method Details

#walmart_catalog_item?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'app/concerns/models/catalog_item_walmart_helper.rb', line 18

def walmart_catalog_item?
  CatalogConstants::WALMART_CATALOGS.include?(catalog_id)
end

#walmart_retire_itemHash

Retire a Walmart listing via the DELETE /v3/items/sku API
and transition the catalog item to discontinued on success.

See: https://developer.walmart.com/us-marketplace/reference/retireanitem

Returns:

  • (Hash)

    { status:, message:, ecl: }



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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/concerns/models/catalog_item_walmart_helper.rb', line 27

def walmart_retire_item
  return { status: :skipped, message: 'Not a Walmart item' } unless walmart_catalog_item?
  return { status: :skipped, message: 'Orchestrator could not be loaded' } unless (orchestrator = catalog.load_orchestrator)

  sku = reported_vendor_sku.presence || self.sku
  return { status: :error, message: 'No SKU available for this catalog item' } if sku.blank?

  transport = Transport::HttpWalmartSellerApiConnection.new(profile: orchestrator.transporter_profile)
  url = "#{orchestrator.items_remote_path}/#{ERB::Util.url_encode(sku)}"

  # Create an ECL to track the API call
  ecl = EdiCommunicationLog.create_outbound_file_from_data(
    data: { sku: sku, action: 'RETIRE' }.to_json,
    data_type: 'json',
    file_extension: 'json',
    partner: orchestrator.partner,
    category: 'listing_data (RETIRE)',
    resources: [self],
    file_info: {
      sku: sku,
      catalog_item_id: id,
      operation: 'RETIRE'
    }
  )

  res = transport.send_data('', url, 'delete')
  response_body = res[:http_result]&.body.to_s
  http_code = res[:http_result]&.status.to_s
  already_retired = http_code == '404' && response_body.include?(WALMART_ALREADY_RETIRED_ERROR_CODE)

  ecl.notes = "HTTP CODE: #{http_code}, HTTP BODY: #{response_body.first(500)}, Timestamp: #{Time.current.to_datetime.to_fs(:crm_default)}"
  ecl.notes += ' [TREATED AS ALREADY-RETIRED]' if already_retired
  ecl.transmit_datetime = Time.current

  result = if res[:success] || already_retired
             ecl.start_process! # Goes to :processing (Walmart confirms outbound) or :processed
             ecl.complete! if ecl.processing? # Direct API call — no feed polling needed, mark as complete
             message = already_retired ? "SKU #{sku}: already retired on Walmart (404)" : "SKU #{sku}: listing retired from Walmart!"
             { status: :success, message: message, ecl: ecl }
           else
             ecl.error
             { status: :error, message: "SKU #{sku}: could not retire listing from Walmart. HTTP #{http_code}: #{response_body.first(200)}", ecl: ecl }
           end

  # After a successful RETIRE, transition pending_discontinue -> discontinued
  discontinue! if result[:status] == :success && pending_discontinue? && can_discontinue?

  result
end