Class: Edi::Walmart::Orchestrator

Inherits:
BaseOrchestrator show all
Defined in:
app/services/edi/walmart/orchestrator.rb

Overview

Service object: orchestrator.

Constant Summary collapse

GOLIVE_DATE_STR =

Golive date str.

'July 25, 2025'
EARLY_LABEL_PURCHASE_ENABLED_US =

Enable early label purchase for Walmart orders (labels purchased at order release, not ship-label time)
Set to true to enable, false to disable

false
EARLY_LABEL_PURCHASE_ENABLED_CA =

Early label purchase enabled ca.

false

Constants inherited from BaseOrchestrator

BaseOrchestrator::DEFAULT_PENDING_DISCONTINUE_LIFETIME, BaseOrchestrator::ORCHESTRATORS, BaseOrchestrator::RECOMMENDED_EXECUTE_FLOW_EVERY_X_HOUR

Instance Attribute Summary

Attributes inherited from BaseOrchestrator

#config, #logger, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseOrchestrator

all_orchestrators_class, build, build_customer_id_to_partner_key_map, cached_build, cached_orchestrators, catalog_id_to_pending_discontinue_lifetime, catalog_ids_edi_enabled, #customer, #customer_catalog, customer_id_to_partner_key_map, #customer_ids, customer_ids_edi_enabled, customer_ids_with_invoice_message_enabled, #customers, execute_discontinue_flow, execute_flow, execute_inventory_flow, execute_listing_message_feed_flow, execute_order_flow, execute_price_flow, execute_product_data_flow, #execute_product_data_flow, #ignore_back_orders, #initialize, orchestrator_for_customer_id, orchestrators, #pending_discontinue_lifetime, #product_data_enabled?, #should_execute_flow?, #should_execute_order_flow?, #should_execute_product_data_flow?, #test_mode?

Constructor Details

This class inherits a constructor from Edi::BaseOrchestrator

Class Method Details

.execute_feed_submission_result_processor(options = {}) ⇒ Object



78
79
80
# File 'app/services/edi/walmart/orchestrator.rb', line 78

def self.execute_feed_submission_result_processor(options = {})
  orchestrators(options).each { |o| o.feed_submission_result_processor.process }
end

.partnersObject



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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/services/edi/walmart/orchestrator.rb', line 17

def self.partners
  {
    walmart_seller_us: {
      active: true,
      partner: :walmart_seller_us,
      customer_id: 23_041_827,
      fulfillment_center_id: '10002649057',
      locales: ['en_US'],
      business_unit: 'WALMART_US',
      default_locale: 'en',
      inventory_message_enabled: true,
      support_contact: 'Soumitro.Biswas0@walmart.com',
      price_message_enabled: true,
      ship_with_walmart_enabled: true, # Enable "Ship with Walmart" discounted shipping rates
      early_label_purchase_enabled: EARLY_LABEL_PURCHASE_ENABLED_US,
      transporter: :http_walmart_seller_api,
      transporter_profile: :walmart_seller_us_api,
      inventory_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_us_api, :api_host)}/v3/inventory",
      feed_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_us_api, :api_host)}/v3/feeds",
      order_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_us_api, :api_host)}/v3/orders",
      items_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_us_api, :api_host)}/v3/items",
      ship_with_walmart_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_us_api, :api_host)}/v3/shipping/labels",
      failure_timeout_in_minutes: 1440,
      execute_inventory_flow_every_x_hour: 1,
      execute_price_flow_every_x_hour: 24,
      execute_order_flow_every_x_hour: 1,
      listing_message_feed_enabled: false,
      currency: 'USD'
    },
    walmart_seller_ca: {
      active: true,
      partner: :walmart_seller_ca,
      customer_id: 21_009_368,
      fulfillment_center_id: '10001201755',
      locales: %w[en_CA fr_CA],
      business_unit: 'WALMART_CA',
      default_locale: 'en',
      inventory_message_enabled: true,
      support_contact: 'Soumitro.Biswas0@walmart.com',
      price_message_enabled: true,
      ship_with_walmart_enabled: true, # Enable "Ship with Walmart" discounted shipping rates
      early_label_purchase_enabled: EARLY_LABEL_PURCHASE_ENABLED_CA,
      transporter: :http_walmart_seller_api,
      transporter_profile: :walmart_seller_ca_api,
      # Use global endpoints with WM_MARKET header (set via profile[:market])
      # See: https://developer.walmart.com/global-marketplace/reference/tokenapi
      inventory_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_ca_api, :api_host)}/v3/inventory",
      feed_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_ca_api, :api_host)}/v3/feeds",
      order_message_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_ca_api, :api_host)}/v3/orders",
      items_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_ca_api, :api_host)}/v3/items",
      ship_with_walmart_remote_path: "https://#{Heatwave::Configuration.fetch(:walmart_seller_ca_api, :api_host)}/v3/shipping/labels",
      failure_timeout_in_minutes: 1440,
      execute_inventory_flow_every_x_hour: 1,
      execute_price_flow_every_x_hour: 24,
      execute_order_flow_every_x_hour: 1,
      listing_message_feed_enabled: false,
      currency: 'CAD'
    }
  }
end

Instance Method Details

#acknowledge_message_enabled?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'app/services/edi/walmart/orchestrator.rb', line 128

def acknowledge_message_enabled?
  try(:order_message_remote_path).present?
end

#acknowledge_message_senderObject



132
133
134
135
136
# File 'app/services/edi/walmart/orchestrator.rb', line 132

def acknowledge_message_sender
  return Edi::NullProcessor.new(self, :acknowledge_message_sender, options) unless acknowledge_message_enabled?

  AcknowledgeMessageSender.new(self, options)
end

#buy_box_status_enabled?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'app/services/edi/walmart/orchestrator.rb', line 219

def buy_box_status_enabled?
  try(:product_pricing_remote_path).present?
end

#buy_box_status_retrieverObject



223
224
225
226
227
# File 'app/services/edi/walmart/orchestrator.rb', line 223

def buy_box_status_retriever
  return Edi::NullProcessor.new(self, :buy_box_status_retriever, options) unless buy_box_status_enabled?

  BuyBoxStatusRetriever.new(self, options)
end

#catalog_item_information_enabled?Boolean

Returns:

  • (Boolean)


209
210
211
# File 'app/services/edi/walmart/orchestrator.rb', line 209

def catalog_item_information_enabled?
  try(:items_remote_path).present?
end

#catalog_item_information_processorObject



253
254
255
256
257
# File 'app/services/edi/walmart/orchestrator.rb', line 253

def catalog_item_information_processor
  return Edi::NullProcessor.new(self, :catalog_item_information_processor, options) unless catalog_item_information_enabled?

  CatalogItemInformationProcessor.new(self, options)
end

#catalog_item_information_retrieverObject



213
214
215
216
217
# File 'app/services/edi/walmart/orchestrator.rb', line 213

def catalog_item_information_retriever
  return Edi::NullProcessor.new(self, :catalog_item_information_retriever, options) unless catalog_item_information_enabled?

  CatalogItemInformationRetriever.new(self, options)
end

#confirm_message_enabled?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'app/services/edi/walmart/orchestrator.rb', line 98

def confirm_message_enabled?
  try(:order_message_remote_path).present?
end

#confirm_message_processorObject



116
117
118
119
120
# File 'app/services/edi/walmart/orchestrator.rb', line 116

def confirm_message_processor
  return Edi::NullProcessor.new(self, :confirm_message_processor, options) unless confirm_message_enabled?

  ConfirmMessageProcessor.new(self, options)
end

#confirm_message_senderObject



122
123
124
125
126
# File 'app/services/edi/walmart/orchestrator.rb', line 122

def confirm_message_sender
  return Edi::NullProcessor.new(self, :confirm_message_sender, options) unless confirm_message_enabled?

  ConfirmMessageSender.new(self, options)
end

#confirm_outbound_processing?Boolean

Walmart is a two stage process on feeds (processing -> complete)

Returns:

  • (Boolean)


331
332
333
# File 'app/services/edi/walmart/orchestrator.rb', line 331

def confirm_outbound_processing?
  true
end

#delete_listing_message_processorObject



279
280
281
282
283
# File 'app/services/edi/walmart/orchestrator.rb', line 279

def delete_listing_message_processor
  return Edi::NullProcessor.new(self, :delete_listing_message_processor, options) unless listing_message_enabled?

  DeleteListingMessageProcessor.new(self, options)
end

#discontinue_flow_processorObject



326
327
328
# File 'app/services/edi/walmart/orchestrator.rb', line 326

def discontinue_flow_processor
  DiscontinueFlowProcessor.new(self, options)
end

#early_label_purchase_enabled?Boolean

Check if early label purchase is enabled for this partner
When enabled, labels are purchased at order release instead of at ship-label time
Set to false to disable the feature; set to true to enable it

Returns:

  • (Boolean)

    true if early label purchase is enabled



112
113
114
# File 'app/services/edi/walmart/orchestrator.rb', line 112

def early_label_purchase_enabled?
  try(:early_label_purchase_enabled) == true && ship_with_walmart_enabled?
end

#execute_discontinue_flowObject



320
321
322
323
324
# File 'app/services/edi/walmart/orchestrator.rb', line 320

def execute_discontinue_flow
  return false unless active

  discontinue_flow_processor.process
end

#execute_inventory_flow(use_delta_since_last_message: false) ⇒ Object



299
300
301
302
303
304
# File 'app/services/edi/walmart/orchestrator.rb', line 299

def execute_inventory_flow(use_delta_since_last_message: false)
  return false unless active

  inventory_message_processor.process(use_delta_since_last_message:) # Generate an inventory feed message
  inventory_message_sender.process # Send it
end

#execute_listing_message_feed_flowObject



313
314
315
316
317
318
# File 'app/services/edi/walmart/orchestrator.rb', line 313

def execute_listing_message_feed_flow
  return false unless active

  listing_message_feed_processor.process # Generate a listing message feed message
  listing_message_feed_sender.process # Send it
end

#execute_order_flowObject



285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'app/services/edi/walmart/orchestrator.rb', line 285

def execute_order_flow
  return unless active

  order_message_retriever.process
  sleep(1)
  order_message_processor.process
  sleep(1)
  acknowledge_message_sender.process
  sleep(1)
  confirm_message_sender.process
  # sleep(1)
  # execute_fba_order_flow # need this to run less frequently or to remove ECLs where we skip all the processed fba_orders
end

#execute_price_flow(use_delta_since_last_message: false) ⇒ Object



306
307
308
309
310
311
# File 'app/services/edi/walmart/orchestrator.rb', line 306

def execute_price_flow(use_delta_since_last_message: false)
  return false unless active

  price_message_processor.process(use_delta_since_last_message:) # Generate a price feed message
  price_message_sender.process # Send it
end

#feed_submission_result_processorObject



205
206
207
# File 'app/services/edi/walmart/orchestrator.rb', line 205

def feed_submission_result_processor
  FeedSubmissionResultProcessor.new(self, options)
end

#inventory_message_enabled?Boolean

Returns:

  • (Boolean)


154
155
156
157
158
159
# File 'app/services/edi/walmart/orchestrator.rb', line 154

def inventory_message_enabled?
  # `try` (not bare call) because per-partner attr_accessors are only
  # defined for keys actually present in the partner config hash —
  # mirrors the Amazon fix landed for AppSignal #5595.
  try(:inventory_message_enabled).present?
end

#inventory_message_processorObject



161
162
163
164
165
# File 'app/services/edi/walmart/orchestrator.rb', line 161

def inventory_message_processor
  return Edi::NullProcessor.new(self, :inventory_message_processor, options) unless inventory_message_enabled?

  InventoryMessageProcessor.new(self, options)
end

#inventory_message_senderObject



167
168
169
170
171
# File 'app/services/edi/walmart/orchestrator.rb', line 167

def inventory_message_sender
  return Edi::NullProcessor.new(self, :inventory_message_sender, options) unless inventory_message_enabled?

  InventoryMessageSender.new(self, options)
end

#invoice_message_enabled?Boolean

Returns:

  • (Boolean)


138
139
140
# File 'app/services/edi/walmart/orchestrator.rb', line 138

def invoice_message_enabled?
  false
end

#invoice_message_processorObject



142
143
144
# File 'app/services/edi/walmart/orchestrator.rb', line 142

def invoice_message_processor
  Edi::NullProcessor.new(self, :invoice_message_processor, options)
end

#listing_item_information_processorObject



235
236
237
238
239
# File 'app/services/edi/walmart/orchestrator.rb', line 235

def listing_item_information_processor
  return Edi::NullProcessor.new(self, :listing_item_information_processor, options) unless listing_message_enabled?

  ListingItemInformationProcessor.new(self, options)
end

#listing_item_information_retrieverObject



229
230
231
232
233
# File 'app/services/edi/walmart/orchestrator.rb', line 229

def listing_item_information_retriever
  return Edi::NullProcessor.new(self, :listing_item_information_retriever, options) unless listing_message_enabled?

  ListingItemInformationRetriever.new(self, options)
end

#listing_item_schema_processorObject



247
248
249
250
251
# File 'app/services/edi/walmart/orchestrator.rb', line 247

def listing_item_schema_processor
  return Edi::NullProcessor.new(self, :listing_item_schema_processor, options) unless listing_schema_message_enabled?

  ListingItemSchemaProcessor.new(self, options)
end

#listing_item_schema_retrieverObject



241
242
243
244
245
# File 'app/services/edi/walmart/orchestrator.rb', line 241

def listing_item_schema_retriever
  return Edi::NullProcessor.new(self, :listing_item_schema_retriever, options) unless listing_schema_message_enabled?

  ListingItemSchemaRetriever.new(self, options)
end

#listing_message_enabled?Boolean

Returns:

  • (Boolean)


259
260
261
# File 'app/services/edi/walmart/orchestrator.rb', line 259

def listing_message_enabled?
  try(:listing_message_remote_path).present?
end

#listing_message_feed_enabled?Boolean

Returns:

  • (Boolean)


189
190
191
# File 'app/services/edi/walmart/orchestrator.rb', line 189

def listing_message_feed_enabled?
  listing_message_feed_enabled
end

#listing_message_feed_processorObject



199
200
201
202
203
# File 'app/services/edi/walmart/orchestrator.rb', line 199

def listing_message_feed_processor
  return Edi::NullProcessor.new(self, :listing_message_feed_processor, options) unless listing_message_feed_enabled?

  ListingMessageFeedProcessor.new(self, options)
end

#listing_message_feed_senderObject



193
194
195
196
197
# File 'app/services/edi/walmart/orchestrator.rb', line 193

def listing_message_feed_sender
  return Edi::NullProcessor.new(self, :listing_message_feed_sender, options) unless listing_message_feed_enabled?

  ListingMessageFeedSender.new(self, options)
end

#listing_message_processorObject



273
274
275
276
277
# File 'app/services/edi/walmart/orchestrator.rb', line 273

def listing_message_processor
  return Edi::NullProcessor.new(self, :listing_message_processor, options) unless listing_message_enabled?

  ListingMessageProcessor.new(self, options)
end

#listing_message_senderObject



267
268
269
270
271
# File 'app/services/edi/walmart/orchestrator.rb', line 267

def listing_message_sender
  return Edi::NullProcessor.new(self, :listing_message_sender, options) unless listing_message_enabled?

  ListingMessageSender.new(self, options)
end

#listing_schema_message_enabled?Boolean

Returns:

  • (Boolean)


263
264
265
# File 'app/services/edi/walmart/orchestrator.rb', line 263

def listing_schema_message_enabled?
  try(:listing_schema_message_enabled).present?
end

#order_message_enabled?Boolean

Returns:

  • (Boolean)


82
83
84
# File 'app/services/edi/walmart/orchestrator.rb', line 82

def order_message_enabled?
  try(:order_message_remote_path).present?
end

#order_message_processorObject



92
93
94
95
96
# File 'app/services/edi/walmart/orchestrator.rb', line 92

def order_message_processor
  return Edi::NullProcessor.new(self, :order_message_processor, options) unless order_message_enabled?

  OrderMessageProcessor.new(self, options)
end

#order_message_retrieverObject



86
87
88
89
90
# File 'app/services/edi/walmart/orchestrator.rb', line 86

def order_message_retriever
  return Edi::NullProcessor.new(self, :order_message_retriever, options) unless order_message_enabled?

  OrderMessageRetriever.new(self, options)
end

#orders_with_walmart_po(po_number) ⇒ Object

Find orders by Walmart PO number for duplicate checking



340
341
342
343
344
345
# File 'app/services/edi/walmart/orchestrator.rb', line 340

def orders_with_walmart_po(po_number)
  Order.joins(:customer)
       .where(customers: { id: customer_ids })
       .where(edi_po_number: po_number)
       .where('orders.created_at > ?', 13.months.ago)
end

#price_message_enabled?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'app/services/edi/walmart/orchestrator.rb', line 173

def price_message_enabled?
  price_message_enabled
end

#price_message_processorObject



183
184
185
186
187
# File 'app/services/edi/walmart/orchestrator.rb', line 183

def price_message_processor
  return Edi::NullProcessor.new(self, :price_message_processor, options) unless price_message_enabled?

  PriceMessageProcessor.new(self, options)
end

#price_message_senderObject



177
178
179
180
181
# File 'app/services/edi/walmart/orchestrator.rb', line 177

def price_message_sender
  return Edi::NullProcessor.new(self, :price_message_sender, options) unless price_message_enabled?

  PriceMessageSender.new(self, options)
end

#pull_all_catalog_information(dry_run: false) ⇒ Object

Pull all catalog items for synchronization



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'app/services/edi/walmart/orchestrator.rb', line 371

def pull_all_catalog_information(dry_run: false)
  results = []
  offset = 0
  limit = 200

  loop do
    ecl = catalog_item_information_retriever.process_all(offset: offset, limit: limit)
    break unless ecl

    result = catalog_item_information_processor.process(ecl, dry_run: dry_run)
    results << result

    # Check for more pages
    data = JSON.parse(ecl.data).with_indifferent_access
    total_items = data[:totalItems].to_i
    break if offset + limit >= total_items

    offset += limit
    sleep(0.5)
  end

  results
end

#pull_catalog_information(catalog_item) ⇒ Object

Pull catalog information for a specific catalog item by SKU



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'app/services/edi/walmart/orchestrator.rb', line 348

def pull_catalog_information(catalog_item)
  sku = catalog_item.reported_vendor_sku || catalog_item.sku
  raise "No SKU for catalog_item #{catalog_item.id}" if sku.blank?

  ecl = catalog_item_information_retriever.process(
    sku: sku,
    file_info: {
      sku: sku,
      catalog_item_id: catalog_item.id,
      item_id: catalog_item.item_id
    }
  )

  if ecl
    Rails.logger.debug { "Walmart orchestrator#pull_catalog_information, ecl: #{ecl.id}" }
    catalog_item_information_processor.process(ecl)
  else
    Rails.logger.error "Walmart orchestrator#pull_catalog_information for catalog item #{catalog_item.id} yielded no ecl (sku #{sku} not found?)"
    nil
  end
end

#return_notification_message_enabled?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'app/services/edi/walmart/orchestrator.rb', line 146

def return_notification_message_enabled?
  false
end

#return_notification_message_processorObject



150
151
152
# File 'app/services/edi/walmart/orchestrator.rb', line 150

def return_notification_message_processor
  Edi::NullProcessor.new(self, :return_notification_message_processor, options)
end

#ship_code_mapperObject



335
336
337
# File 'app/services/edi/walmart/orchestrator.rb', line 335

def ship_code_mapper
  ShipCodeMapper.new(self)
end

#ship_with_walmart_enabled?Boolean

Check if "Ship with Walmart" (SWW) discounted shipping is enabled for this partner

Returns:

  • (Boolean)

    true if SWW rates and label purchasing are enabled



104
105
106
# File 'app/services/edi/walmart/orchestrator.rb', line 104

def ship_with_walmart_enabled?
  try(:ship_with_walmart_enabled) == true && try(:ship_with_walmart_remote_path).present?
end