mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-28 21:07:16 +00:00
73 lines
2.1 KiB
Ruby
73 lines
2.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Finds wholesale offers for retail products.
|
|
class FdcOfferBroker
|
|
# TODO: Find a better way to provide this data.
|
|
Solution = Struct.new(:product, :factor, :offer)
|
|
RetailSolution = Struct.new(:retail_product_id, :factor)
|
|
|
|
attr_reader :catalog
|
|
|
|
def initialize(catalog)
|
|
@catalog = catalog
|
|
end
|
|
|
|
def best_offer(product_id)
|
|
Solution.new(
|
|
wholesale_product(product_id),
|
|
contained_quantity(product_id),
|
|
offer_of(wholesale_product(product_id))
|
|
)
|
|
end
|
|
|
|
def wholesale_product(product_id)
|
|
production_flow = catalog.item("#{product_id}/AsPlannedProductionFlow")
|
|
|
|
if production_flow
|
|
production_flow.product
|
|
else
|
|
# We didn't find a wholesale variant, falling back to the given product.
|
|
catalog.item(product_id)
|
|
end
|
|
end
|
|
|
|
def contained_quantity(product_id)
|
|
consumption_flow = catalog.item("#{product_id}/AsPlannedConsumptionFlow")
|
|
|
|
# If we don't find a transformation, we return the original product,
|
|
# which contains exactly one of itself (identity).
|
|
consumption_flow&.quantity&.value&.to_i || 1
|
|
end
|
|
|
|
def wholesale_to_retail(wholesale_product_id)
|
|
production_flow = flow_producing(wholesale_product_id)
|
|
|
|
return RetailSolution.new(wholesale_product_id, 1) if production_flow.nil?
|
|
|
|
consumption_flow = catalog.item(
|
|
production_flow.semanticId.sub("AsPlannedProductionFlow", "AsPlannedConsumptionFlow")
|
|
)
|
|
retail_product_id = consumption_flow.product.semanticId
|
|
|
|
contained_quantity = consumption_flow.quantity.value.to_i
|
|
|
|
RetailSolution.new(retail_product_id, contained_quantity)
|
|
end
|
|
|
|
def offer_of(product)
|
|
product&.catalogItems&.first&.offers&.first&.tap do |offer|
|
|
# Unfortunately, the imported catalog doesn't provide the reverse link:
|
|
offer.offeredItem = product
|
|
end
|
|
end
|
|
|
|
def flow_producing(wholesale_product_id)
|
|
@production_flows_by_product_id ||= production_flows.index_by { |flow| flow.product.semanticId }
|
|
@production_flows_by_product_id[wholesale_product_id]
|
|
end
|
|
|
|
def production_flows
|
|
@production_flows ||= catalog.select_type("dfc-b:AsPlannedProductionFlow")
|
|
end
|
|
end
|