mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-19 04:49:15 +00:00
Merge pull request #13049 from mkllnk/dfc-wholesale-stock
Calculate stock from DFC wholesale variants
This commit is contained in:
@@ -19,15 +19,12 @@ module Admin
|
||||
.find(params.require(:enterprise_id))
|
||||
|
||||
catalog_url = params.require(:catalog_url)
|
||||
broker = FdcOfferBroker.new(spree_current_user, catalog_url)
|
||||
catalog = DfcCatalog.load(spree_current_user, catalog_url)
|
||||
catalog.apply_wholesale_values!
|
||||
|
||||
# * First step: import all products for given enterprise.
|
||||
# * Second step: render table and let user decide which ones to import.
|
||||
imported = broker.catalog.map do |subject|
|
||||
next unless subject.is_a? DataFoodConsortium::Connector::SuppliedProduct
|
||||
|
||||
adjust_to_wholesale_price(broker, subject)
|
||||
|
||||
imported = catalog.products.map do |subject|
|
||||
existing_variant = enterprise.supplied_variants.linked_to(subject.semanticId)
|
||||
|
||||
if existing_variant
|
||||
@@ -44,24 +41,5 @@ module Admin
|
||||
flash[:error] = e.message
|
||||
redirect_to admin_product_import_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def adjust_to_wholesale_price(broker, product)
|
||||
transformation = broker.best_offer(product.semanticId)
|
||||
|
||||
return if transformation.factor == 1
|
||||
|
||||
wholesale_variant_price = transformation.offer.price
|
||||
|
||||
return unless wholesale_variant_price
|
||||
|
||||
offer = product.catalogItems&.first&.offers&.first
|
||||
|
||||
return unless offer
|
||||
|
||||
offer.price = wholesale_variant_price.dup
|
||||
offer.price.value = offer.price.value.to_f / transformation.factor
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -117,7 +117,8 @@ class BackorderJob < ApplicationJob
|
||||
end
|
||||
|
||||
def load_broker(user, urls)
|
||||
FdcOfferBroker.new(user, urls.catalog_url)
|
||||
catalog = DfcCatalog.load(user, urls.catalog_url)
|
||||
FdcOfferBroker.new(catalog)
|
||||
end
|
||||
|
||||
def place_order(user, order, orderer, backorder)
|
||||
|
||||
@@ -40,7 +40,10 @@ class StockSyncJob < ApplicationJob
|
||||
end
|
||||
|
||||
def perform(user, catalog_id)
|
||||
products = load_products(user, catalog_id)
|
||||
catalog = DfcCatalog.load(user, catalog_id)
|
||||
catalog.apply_wholesale_values!
|
||||
|
||||
products = catalog.products
|
||||
products_by_id = products.index_by(&:semanticId)
|
||||
product_ids = products_by_id.keys
|
||||
variants = linked_variants(user.enterprises, product_ids)
|
||||
@@ -58,15 +61,6 @@ class StockSyncJob < ApplicationJob
|
||||
end
|
||||
end
|
||||
|
||||
def load_products(user, catalog_id)
|
||||
json_catalog = DfcRequest.new(user).call(catalog_id)
|
||||
graph = DfcIo.import(json_catalog)
|
||||
|
||||
graph.select do |subject|
|
||||
subject.is_a? DataFoodConsortium::Connector::SuppliedProduct
|
||||
end
|
||||
end
|
||||
|
||||
def linked_variants(enterprises, product_ids)
|
||||
Spree::Variant.where(supplier: enterprises)
|
||||
.includes(:semantic_links).references(:semantic_links)
|
||||
|
||||
@@ -40,7 +40,8 @@ class BackorderUpdater
|
||||
reference_link = variants[0].semantic_links[0].semantic_id
|
||||
urls = FdcUrlBuilder.new(reference_link)
|
||||
orderer = FdcBackorderer.new(user, urls)
|
||||
broker = FdcOfferBroker.new(user, urls.catalog_url)
|
||||
catalog = DfcCatalog.load(user, urls.catalog_url)
|
||||
broker = FdcOfferBroker.new(catalog)
|
||||
|
||||
updated_lines = update_order_lines(backorder, order_cycle, variants, broker, orderer)
|
||||
unprocessed_lines = backorder.lines.to_set - updated_lines
|
||||
|
||||
@@ -6,19 +6,10 @@ class FdcOfferBroker
|
||||
Solution = Struct.new(:product, :factor, :offer)
|
||||
RetailSolution = Struct.new(:retail_product_id, :factor)
|
||||
|
||||
def self.load_catalog(user, catalog_url)
|
||||
api = DfcRequest.new(user)
|
||||
catalog_json = api.call(catalog_url)
|
||||
DfcIo.import(catalog_json)
|
||||
end
|
||||
attr_reader :catalog
|
||||
|
||||
def initialize(user, catalog_url)
|
||||
@user = user
|
||||
@catalog_url = catalog_url
|
||||
end
|
||||
|
||||
def catalog
|
||||
@catalog ||= self.class.load_catalog(@user, @catalog_url)
|
||||
def initialize(catalog)
|
||||
@catalog = catalog
|
||||
end
|
||||
|
||||
def best_offer(product_id)
|
||||
@@ -30,18 +21,18 @@ class FdcOfferBroker
|
||||
end
|
||||
|
||||
def wholesale_product(product_id)
|
||||
production_flow = catalog_item("#{product_id}/AsPlannedProductionFlow")
|
||||
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)
|
||||
catalog.item(product_id)
|
||||
end
|
||||
end
|
||||
|
||||
def contained_quantity(product_id)
|
||||
consumption_flow = catalog_item("#{product_id}/AsPlannedConsumptionFlow")
|
||||
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).
|
||||
@@ -53,7 +44,7 @@ class FdcOfferBroker
|
||||
|
||||
return RetailSolution.new(wholesale_product_id, 1) if production_flow.nil?
|
||||
|
||||
consumption_flow = catalog_item(
|
||||
consumption_flow = catalog.item(
|
||||
production_flow.semanticId.sub("AsPlannedProductionFlow", "AsPlannedConsumptionFlow")
|
||||
)
|
||||
retail_product_id = consumption_flow.product.semanticId
|
||||
@@ -70,19 +61,12 @@ class FdcOfferBroker
|
||||
end
|
||||
end
|
||||
|
||||
def catalog_item(id)
|
||||
@catalog_by_id ||= catalog.index_by(&:semanticId)
|
||||
@catalog_by_id[id]
|
||||
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 do |i|
|
||||
i.semanticType == "dfc-b:AsPlannedProductionFlow"
|
||||
end
|
||||
@production_flows ||= catalog.select_type("dfc-b:AsPlannedProductionFlow")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user