From ddaeff7c53bae0c3bb116fbdeafbd53b061f0c45 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 18 Dec 2024 16:04:27 +1100 Subject: [PATCH] Use DfcCatalog in offer broker --- .../admin/dfc_product_imports_controller.rb | 4 +-- app/jobs/backorder_job.rb | 3 +- app/services/backorder_updater.rb | 3 +- app/services/fdc_offer_broker.rb | 32 +++++-------------- .../dfc_provider/app/services/dfc_catalog.rb | 17 ++++++++++ .../spec/services/dfc_catalog_spec.rb | 8 ++--- spec/jobs/complete_backorder_job_spec.rb | 5 +-- spec/services/fdc_backorderer_spec.rb | 13 ++++---- spec/services/fdc_offer_broker_spec.rb | 8 +++-- 9 files changed, 49 insertions(+), 44 deletions(-) diff --git a/app/controllers/admin/dfc_product_imports_controller.rb b/app/controllers/admin/dfc_product_imports_controller.rb index c17a428c75..0178d5518e 100644 --- a/app/controllers/admin/dfc_product_imports_controller.rb +++ b/app/controllers/admin/dfc_product_imports_controller.rb @@ -19,8 +19,8 @@ module Admin .find(params.require(:enterprise_id)) catalog_url = params.require(:catalog_url) - broker = FdcOfferBroker.new(spree_current_user, catalog_url) - catalog = DfcCatalog.new(broker.catalog) + catalog = DfcCatalog.load(spree_current_user, catalog_url) + broker = FdcOfferBroker.new(catalog) # * First step: import all products for given enterprise. # * Second step: render table and let user decide which ones to import. diff --git a/app/jobs/backorder_job.rb b/app/jobs/backorder_job.rb index c2a0b45527..a0a3c168e5 100644 --- a/app/jobs/backorder_job.rb +++ b/app/jobs/backorder_job.rb @@ -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) diff --git a/app/services/backorder_updater.rb b/app/services/backorder_updater.rb index e57e59ff6c..bb163c8be0 100644 --- a/app/services/backorder_updater.rb +++ b/app/services/backorder_updater.rb @@ -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 diff --git a/app/services/fdc_offer_broker.rb b/app/services/fdc_offer_broker.rb index c4108ee26c..5071028eac 100644 --- a/app/services/fdc_offer_broker.rb +++ b/app/services/fdc_offer_broker.rb @@ -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 diff --git a/engines/dfc_provider/app/services/dfc_catalog.rb b/engines/dfc_provider/app/services/dfc_catalog.rb index ace46a51d0..42f0df63cf 100644 --- a/engines/dfc_provider/app/services/dfc_catalog.rb +++ b/engines/dfc_provider/app/services/dfc_catalog.rb @@ -1,6 +1,14 @@ # frozen_string_literal: true class DfcCatalog + def self.load(user, catalog_url) + api = DfcRequest.new(user) + catalog_json = api.call(catalog_url) + graph = DfcIo.import(catalog_json) + + new(graph) + end + def initialize(graph) @graph = graph end @@ -10,4 +18,13 @@ class DfcCatalog subject.is_a? DataFoodConsortium::Connector::SuppliedProduct end end + + def item(semantic_id) + @items ||= @graph.index_by(&:semanticId) + @items[semantic_id] + end + + def select_type(semantic_type) + @graph.select { |i| i.semanticType == semantic_type } + end end diff --git a/engines/dfc_provider/spec/services/dfc_catalog_spec.rb b/engines/dfc_provider/spec/services/dfc_catalog_spec.rb index c050e9f5d7..35b4a1082d 100644 --- a/engines/dfc_provider/spec/services/dfc_catalog_spec.rb +++ b/engines/dfc_provider/spec/services/dfc_catalog_spec.rb @@ -3,11 +3,11 @@ require_relative "../spec_helper" RSpec.describe DfcCatalog do - subject(:catalog) { DfcCatalog.new(fdc_catalog_graph) } - let(:fdc_catalog_graph) { - VCR.use_cassette(:fdc_catalog) { broker.catalog } + subject(:catalog) { + VCR.use_cassette(:fdc_catalog) { + DfcCatalog.load(user, catalog_url) + } } - let(:broker) { FdcOfferBroker.new(user, catalog_url) } let(:user) { build(:testdfc_user) } let(:catalog_url) { "https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod/SuppliedProducts" diff --git a/spec/jobs/complete_backorder_job_spec.rb b/spec/jobs/complete_backorder_job_spec.rb index ad6479079f..0bc1a741e3 100644 --- a/spec/jobs/complete_backorder_job_spec.rb +++ b/spec/jobs/complete_backorder_job_spec.rb @@ -14,13 +14,14 @@ RSpec.describe CompleteBackorderJob do let(:orderer) { FdcBackorderer.new(user, urls) } let(:order) { backorder = orderer.find_or_build_order(ofn_order) - broker = FdcOfferBroker.new(user, urls.catalog_url) + catalog = DfcCatalog.load(user, urls.catalog_url) + broker = FdcOfferBroker.new(catalog) bean_offer = broker.best_offer(product_link).offer bean_line = orderer.find_or_build_order_line(backorder, bean_offer) bean_line.quantity = 3 - chia = broker.catalog_item(chia_seed_retail_link) + chia = catalog.item(chia_seed_retail_link) chia_offer = broker.offer_of(chia) chia_line = orderer.find_or_build_order_line(backorder, chia_offer) chia_line.quantity = 5 diff --git a/spec/services/fdc_backorderer_spec.rb b/spec/services/fdc_backorderer_spec.rb index e784203f27..b2aea87d14 100644 --- a/spec/services/fdc_backorderer_spec.rb +++ b/spec/services/fdc_backorderer_spec.rb @@ -31,9 +31,9 @@ RSpec.describe FdcBackorderer do expect(backorder.lines).to eq [] # Add items and place the new order: - catalog = FdcOfferBroker.load_catalog(order.distributor.owner, urls.catalog_url) - product = catalog.find { |i| i.semanticType == "dfc-b:SuppliedProduct" } - offer = FdcOfferBroker.new(nil, nil).offer_of(product) + catalog = DfcCatalog.load(order.distributor.owner, urls.catalog_url) + product = catalog.products.first + offer = FdcOfferBroker.new(nil).offer_of(product) line = subject.find_or_build_order_line(backorder, offer) line.quantity = 3 placed_order = subject.send_order(backorder) @@ -74,15 +74,14 @@ RSpec.describe FdcBackorderer do describe "#find_or_build_order_line" do it "add quantity to an existing line item", vcr: true do - catalog = FdcOfferBroker.load_catalog(order.distributor.owner, urls.catalog_url) + catalog = DfcCatalog.load(order.distributor.owner, urls.catalog_url) backorder = subject.find_or_build_order(order) expect(backorder.lines.count).to eq 0 # Add new item to the new order: - catalog = FdcOfferBroker.load_catalog(order.distributor.owner, urls.catalog_url) - product = catalog.find { |i| i.semanticType == "dfc-b:SuppliedProduct" } - offer = FdcOfferBroker.new(nil, nil).offer_of(product) + product = catalog.products.first + offer = FdcOfferBroker.new(nil).offer_of(product) line = subject.find_or_build_order_line(backorder, offer) expect(backorder.lines.count).to eq 1 diff --git a/spec/services/fdc_offer_broker_spec.rb b/spec/services/fdc_offer_broker_spec.rb index 403f3a84cf..6987e0cec5 100644 --- a/spec/services/fdc_offer_broker_spec.rb +++ b/spec/services/fdc_offer_broker_spec.rb @@ -3,9 +3,11 @@ require 'spec_helper' RSpec.describe FdcOfferBroker do - subject { FdcOfferBroker.new(user, catalog_url) } + subject { FdcOfferBroker.new(catalog) } let(:catalog) { - VCR.use_cassette(:fdc_catalog) { subject.catalog } + VCR.use_cassette(:fdc_catalog) { + DfcCatalog.load(user, catalog_url) + } } let(:catalog_url) { "https://env-0105831.jcloud-ver-jpe.ik-server.com/api/dfc/Enterprises/test-hodmedod/SuppliedProducts" @@ -15,7 +17,7 @@ RSpec.describe FdcOfferBroker do } let(:user) { build(:testdfc_user) } let(:product) { - catalog.find { |item| item.semanticType == "dfc-b:SuppliedProduct" } + catalog.products.first } describe ".best_offer" do