Skip to content

Commit

Permalink
refactoring Yandex::ProductsDownloader::ImportingScheme.import_payload
Browse files Browse the repository at this point in the history
  • Loading branch information
rubygitflow committed Feb 10, 2024
1 parent 49dbe2b commit 723b41a
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 64 deletions.
18 changes: 12 additions & 6 deletions app/services/ozon/products_downloader/importing_scheme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
module Ozon
class ProductsDownloader
module ImportingScheme
# rubocop:disable Metrics/AbcSize
def import_payload(items)
list = items.each_with_object({}) { |item, res| res[item[:id].to_s] = item }
exists = []
# 1. making changes to existing products
exists = verify_existing_products(list)
# 2. adding new products
add_new_products(list, list.keys - exists)
end

def verify_existing_products(list)
exists = []
Product.where(
marketplace_credential_id: mp_credential.id,
product_id: list.keys
Expand All @@ -19,9 +24,10 @@ def import_payload(items)
# pp("product.changes=",product.changes) if product.changed?
product.save! if product.changed?
end
rest = list.keys - exists
exists
end

# 2. adding new products
def add_new_products(list, rest)
new_products = []
rest.each do |id|
product = Product.new(
Expand All @@ -33,7 +39,6 @@ def import_payload(items)
end
Product.import(new_products) if new_products.any?
end
# rubocop:enable Metrics/AbcSize

# rubocop:disable Metrics/AbcSize
def prepare_product(product, item)
Expand Down Expand Up @@ -92,7 +97,8 @@ def find_schemes(item)
end

private :import_payload, :prepare_product, :find_price, :find_barcodes,
:find_skus, :find_category_title, :find_status, :find_schemes
:find_skus, :find_category_title, :find_status, :find_schemes,
:verify_existing_products, :add_new_products
end
end
end
100 changes: 71 additions & 29 deletions app/services/yandex/products_downloader/importing_scheme.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,93 @@ module Yandex
class ProductsDownloader
module ImportingScheme
def import_payload(items)
items.each do |item|
offer_id = item[:offer][:offerId]
next unless offer_id
list = items.each_with_object({}) { |item, res| res[item[:offer][:offerId]] = item }
# 1. making changes to existing products
exists = verify_existing_products(list)
# 2. adding new products
add_new_products(list, list.keys - exists)
end

def verify_existing_products(list)
exists = []
Product.where(
marketplace_credential_id: mp_credential.id,
offer_id: list.keys
).find_each do |product|
exists << product.offer_id
product = prepare_product(product, list[product.offer_id])
@parsed_ids << product.offer_id
# We can record the changes somewhere.
# pp("product.changes=",product.changes) if product.changed?
product.save! if product.changed?
end
exists
end

@parsed_ids << offer_id
@product = Product.find_or_initialize_by(
def add_new_products(list, rest)
new_products = []
rest.each do |id|
product = Product.new(
marketplace_credential_id: mp_credential.id,
offer_id:
offer_id: id
)
prepare_product(item)
# We can record the changes somewhere.
# pp("@product.changes=",@product.changes) if @product.changed?
@product.save! if @product.changed?
new_products << prepare_product(product, list[id])
@parsed_ids << id
end
Product.import(new_products) if new_products.any?
end

# rubocop:disable Metrics/AbcSize
def prepare_product(item)
def prepare_product(product, item)
offer = item[:offer]
@product.name = offer.fetch(:name, '')
@product.barcodes = offer.fetch(:barcodes, [])
@product.price = "(#{offer.dig(:basicPrice, :value) || 0},#{offer.dig(:basicPrice, :currencyId) || 'RUR'})".sub(
product.name = offer.fetch(:name, '')
product.barcodes = offer.fetch(:barcodes, [])
product.price = find_price(offer)
product.status = find_status(offer)
product.schemes = find_schemes(offer)
product.images = offer.fetch(:pictures, [])
product.name = offer.fetch(:name, '')
product.description = offer.fetch(:description, nil)

mapping = item[:mapping]
product.product_id = mapping.fetch(:marketModelId, nil)
product.skus = find_skus(mapping)

product.category_title = find_category_title(offer, mapping)
product.scrub_status = 'success'
product
end
# rubocop:enable Metrics/AbcSize

def find_price(offer)
"(#{offer.dig(:basicPrice, :value) || 0},#{offer.dig(:basicPrice, :currencyId) || 'RUR'})".sub(
'.0,', ','
)
@product.status = (@archive ? 'archived' : nil) ||
Handles::ProductsDownloader.take_yandex_card_status(offer)
@product.schemes = offer.fetch(:sellingPrograms, []).filter_map do |elem|
end

def find_status(offer)
(@archive ? 'archived' : nil) ||
Handles::ProductsDownloader.take_yandex_card_status(offer)
end

def find_schemes(offer)
offer.fetch(:sellingPrograms, []).filter_map do |elem|
elem[:sellingProgram] if elem[:status] == 'FINE'
end.sort
@product.images = offer.fetch(:pictures, [])
@product.name = offer.fetch(:name, '')
@product.description = offer.fetch(:description, nil)
end

mapping = item[:mapping]
@product.product_id = mapping.fetch(:marketModelId, nil)
sku = mapping.fetch(:marketSku, nil)
@product.skus = sku ? [sku] : []
def find_category_title(offer, mapping)
offer.fetch(:category, nil) ||
mapping.fetch(:marketCategoryName, nil)
end

@product.category_title = offer.fetch(:category, nil) ||
mapping.fetch(:marketCategoryName, nil)
@product.scrub_status = 'success'
def find_skus(mapping)
sku = mapping.fetch(:marketSku, nil)
sku ? [sku] : []
end
# rubocop:enable Metrics/AbcSize

private :import_payload, :prepare_product
private :import_payload, :prepare_product, :verify_existing_products, :add_new_products,
:find_price, :find_status, :find_schemes, :find_category_title, :find_skus
end
end
end
7 changes: 3 additions & 4 deletions spec/services/ozon/products_downloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,9 @@
end

it 'changes the entry for the same product with new description' do
expect(
Product.find(product_with_outdated_description.id).updated_at
).to be > old_time_product_with_outdated_description
expect(Product.find(product_with_outdated_description.id).description).to eq 'Des_1'
p = Product.find(product_with_outdated_description.id)
expect(p.updated_at).to be > old_time_product_with_outdated_description
expect(p.description).to eq 'Des_1'
end
end
end
Expand Down
86 changes: 61 additions & 25 deletions spec/services/yandex/products_downloader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,71 @@
include_context 'with marketplace_credential yandex offer-mappings'
let(:obj) { described_class.new(marketplace_credential) }

before do
ENV['PRODUCTS_DOWNLOADER_FROM_ARCHIVE'] = 'true'
ENV['PRODUCTS_DOWNLOADER_OZON_DESCRIPTIONS'] = 'false'
obj.call
end
context 'when the products still do not exist' do
before do
ENV['PRODUCTS_DOWNLOADER_FROM_ARCHIVE'] = 'true'
ENV['PRODUCTS_DOWNLOADER_OZON_DESCRIPTIONS'] = 'false'
obj.call
end

it 'gains new records about the products on the marketplace' do
expect(Product.count).to eq 2
end
it 'gains new records about the products on the marketplace' do
expect(Product.count).to eq 2
end

it 'imports product list' do
expect(obj.parsed_ids).to eq %w[
00040263
00040264
]
end

it 'imports product list' do
expect(obj.parsed_ids).to eq %w[
00040263
00040264
]
it 'imports product description' do
product = Product.find_by(offer_id: '00040263')
expect(product.name).to eq 'Ножницы садовые 300 мм серебряный/зеленый'
expect(product.price).to eq '(3790.9,RUR)'
expect(product.status).to eq 'published'
expect(product.barcodes).to eq ['4277136502815']
expect(product.skus).to eq ['100473183912']
expect(product.scrub_status).to eq 'success'
expect(product.schemes).to eq %w[DBS EXPRESS FBS FBY]
expect(product.stock).to be_nil
expect(product.category_title).to eq 'Садовый инвентарь'
expect(product.product_id).to eq '1755955930'
end
end

it 'imports product description' do
product = Product.find_by(offer_id: '00040263')
expect(product.name).to eq 'Ножницы садовые 300 мм серебряный/зеленый'
expect(product.price).to eq '(3790.9,RUR)'
expect(product.status).to eq 'published'
expect(product.barcodes).to eq ['4277136502815']
expect(product.skus).to eq ['100473183912']
expect(product.scrub_status).to eq 'success'
expect(product.schemes).to eq %w[DBS EXPRESS FBS FBY]
expect(product.stock).to be_nil
expect(product.category_title).to eq 'Садовый инвентарь'
expect(product.product_id).to eq '1755955930'
context 'when product already exists in the DB' do
let!(:outdated_product) do
create(:product,
marketplace_credential:,
offer_id: '00040264',
product_id: '1755955934',
name: 'Ножницы садовые 400 мм серебряный/зеленый',
description: 'Des_1',
skus: %w[100473183914],
images: [],
barcodes: %w[4277136502814],
status: 'archived',
scrub_status: 'success',
price: '(0,RUR)',
stock: nil,
category_title: 'Садовый инвентарь',
schemes: %w[DBS EXPRESS FBS FBY])
end
let!(:old_time_outdated_product) { outdated_product.updated_at }

before do
ENV['PRODUCTS_DOWNLOADER_FROM_ARCHIVE'] = 'true'
obj.call
end

it 'changes the entry for the same product with new description' do
p = Product.find(outdated_product.id)
expect(p.updated_at).to be > old_time_outdated_product
expect(p.description).to eq(
'Ножницы садовые KNAUF подходят для первичной обработки поросли веток до 25 мм толщиной.'
)
end
end
end

Expand Down

0 comments on commit 723b41a

Please sign in to comment.