Class: Catalog::PullAmazonCatalogsListingsData
- Inherits:
-
BaseService
- Object
- BaseService
- Catalog::PullAmazonCatalogsListingsData
- Defined in:
- app/services/catalog/pull_amazon_catalogs_listings_data.rb
Defined Under Namespace
Classes: Result
Instance Method Summary collapse
-
#process(options) ⇒ Object
Processes all Amazon catalogs' catalog items, attempting to pull their listing item data.
Methods inherited from BaseService
#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger
Constructor Details
This class inherits a constructor from BaseService
Instance Method Details
#process(options) ⇒ Object
Processes all Amazon catalogs' catalog items, attempting to pull their listing item data. Mark the catalog item as pending_onboarding if no corresponding listing item data found, also accept force_pricing_sync to:
use Catalog::UpdateCatalogItem
- Store the procurement cost price to catalog item's amount
- Store the list price to catalog item's retailer advertised price
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 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 83 84 85 86 87 88 |
# File 'app/services/catalog/pull_amazon_catalogs_listings_data.rb', line 14 def process() [:force_pricing_sync].to_b catalog_ids = [:catalog_ids] catalog_item_ids = [:catalog_item_ids] limit = [:limit]&.to_i = [] catalog_items_updated = [] catalog_items_failed = [] catalogs = Catalog.amazons catalogs = catalogs.where(id: catalog_ids) if catalog_ids.present? logger.info 'Amazon Pull Amazon Catalogs Listings Data processing start.' logger.debug("-- process starting") catalog_items = CatalogItem.amazons_with_asins.joins(:catalog).merge(catalogs) catalog_items = catalog_items.where(id: catalog_item_ids) if catalog_item_ids.present? catalog_items = catalog_items.where(state: %w[active]) catalog_items = catalog_items.limit(limit) if limit.present? if [:refresh_if_older_than].present? catalog_items = catalog_items.where(%{ catalog_items.amazon_info_datetime IS NULL OR (catalog_items.amazon_info_datetime IS NOT NULL and catalog_items.amazon_info_datetime <= ?) }, [:refresh_if_older_than]) end total_records = catalog_items.count logger.info "Found #{total_records} catalog items to process for catalogs: #{catalog_ids&.join(', ') || 'all Amazon'}" # Amazon SP-API rate limits: # - Product Pricing API (Buy Box): 10 requests/sec burst, 0.5/sec restore # - Catalog Items API: 2 requests/sec burst, 2/sec restore # - Listings API: 5 requests/sec burst, 5/sec restore # To be safe, we use 0.6 seconds between each API call (under 2/sec) rate_limit_delay = 0.6.seconds index = 1 catalog_items.find_each do |catalog_item| yield(at: index, total: total_records, message: "Processing catalog item #{catalog_item.id}") if block_given? logger.info "Processing catalog item #{catalog_item.id} for amazon data" action_success_counter = 0 action_msgs = [] begin ["amazon_pull_catalog_information", "amazon_pull_listing_information", "amazon_pull_buy_box_status"].each do |action| res = {} PaperTrail.request(whodunnit: 'Catalog::PullAmazonCatalogsListingsData') do res = catalog_item.send(action) end action_msgs << res[:message] if res[:status] == :success action_success_counter += 1 end logger.info "Processed #{action} for catalog item #{catalog_item.id}, message: #{res[:message]}, success: #{res[:status]}, action_success_counter: #{action_success_counter}" # Rate limiting: sleep between API calls to avoid 429 errors sleep(rate_limit_delay) end rescue StandardError => e # Log the error but continue processing other items logger.error "Error processing catalog item #{catalog_item.id}: #{e.}" logger.error e.backtrace.first(5).join("\n") action_msgs << "Error: #{e.}" end if action_success_counter == 3 catalog_items_updated << catalog_item else catalog_items_failed << catalog_item end += action_msgs index += 1 end Result.new(all_catalog_items_listings_data_pulled: catalog_items_failed.empty?, messages:, catalog_items_updated:, catalog_items_failed:) end |