Files
openfoodnetwork/app/services/dfc_catalog_importer.rb
Maikel Linke 406018e7eb Simplify resetting variants
I was hoping to reduce the query count but it stayed the same. In fact,
I'm expecting the query count to be higher with this version. The
DfcCatalogImporter queries all variants and links at once while the OC
job is not pre-loading the variants at the moment. We can optimise the
job though.

If we kept the old version and there were multiple catalogs per variant
then we would call the importer with the reset multiple times. The job
is iterating through each link only once though. So depending on the
ratio of catalogs to variants, I'm not sure which version would be more
efficient.

No version is properly dealing with the edge-case of multiple catalogs
per variant anyway. Imagine there are two catalogs with different stock
levels. Which one do we choose? Or do we add up?
And if the variant disappears from one catalog we still want to sell it
through the other. But depending on the order of processing, we may
reset the variant if it's missing in the last catalog. But let's worry
about that when it actually happens. Maybe it will be better to restrict
variants to one catalog.
2025-03-27 15:12:45 +11:00

52 lines
1.6 KiB
Ruby

# frozen_string_literal: true
class DfcCatalogImporter
def self.reset_variant(variant)
if variant.on_demand
variant.on_demand = false
else
variant.on_hand = 0
end
end
attr_reader :catalog, :existing_variants
def initialize(existing_variants, catalog)
@existing_variants = existing_variants
@catalog = catalog
end
# Reset stock for any variants that were removed from the catalog.
#
# When variants are removed from the remote catalog, we can't place
# backorders for them anymore. If our copy of the product has limited
# stock then we need to set the stock to zero to prevent any more sales.
#
# But if our product is on-demand/backorderable then our stock level is
# a representation of remaining local stock. We then need to limit sales
# to this local stock and set on-demand to false.
#
# We don't delete the variant because it may come back at a later time and
# we don't want to lose the connection to previous orders.
def reset_absent_variants
absent_variants.map do |variant|
self.class.reset_variant(variant)
end
end
def absent_variants
present_ids = catalog.products.map(&:semanticId)
catalog_url = FdcUrlBuilder.new(present_ids.first).catalog_url
existing_variants
.includes(:semantic_links).references(:semantic_links)
.where.not(semantic_links: { semantic_id: present_ids })
.select do |variant|
# Variants that were in the same catalog before:
variant.semantic_links.map(&:semantic_id).any? do |semantic_id|
FdcUrlBuilder.new(semantic_id).catalog_url == catalog_url
end
end
end
end