From 9f432443129f87722733a593efae308793942399 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 19 Sep 2024 17:06:47 +1000 Subject: [PATCH] Import on-demand stock setting in DFC import --- app/models/spree/variant.rb | 2 ++ .../app/services/catalog_item_builder.rb | 22 +++++++++++++++++++ .../app/services/supplied_product_builder.rb | 1 + .../services/supplied_product_builder_spec.rb | 17 ++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 engines/dfc_provider/app/services/catalog_item_builder.rb diff --git a/app/models/spree/variant.rb b/app/models/spree/variant.rb index 26a601d94ab..5cacf65a9ca 100644 --- a/app/models/spree/variant.rb +++ b/app/models/spree/variant.rb @@ -240,6 +240,8 @@ def set_cost_currency end def create_stock_items + return unless stock_items.empty? + StockLocation.find_each do |stock_location| stock_location.propagate_variant(self) end diff --git a/engines/dfc_provider/app/services/catalog_item_builder.rb b/engines/dfc_provider/app/services/catalog_item_builder.rb new file mode 100644 index 00000000000..e9ba9710dbf --- /dev/null +++ b/engines/dfc_provider/app/services/catalog_item_builder.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class CatalogItemBuilder < DfcBuilder + def self.apply_stock(item, variant) + limit = item&.stockLimitation + + return if limit.blank? + + # Negative stock means "on demand". + # And we are only interested in that for now. + return unless limit.to_i.negative? + + if variant.stock_items.empty? + variant.stock_items << Spree::StockItem.new( + stock_location: DefaultStockLocation.find_or_create, + variant:, + ) + end + + variant.stock_items[0].backorderable = true + end +end diff --git a/engines/dfc_provider/app/services/supplied_product_builder.rb b/engines/dfc_provider/app/services/supplied_product_builder.rb index efd2dbcbacd..1baee71b856 100644 --- a/engines/dfc_provider/app/services/supplied_product_builder.rb +++ b/engines/dfc_provider/app/services/supplied_product_builder.rb @@ -43,6 +43,7 @@ def self.import_variant(supplied_product, supplier) end.tap do |variant| link = supplied_product.semanticId variant.semantic_links.new(semantic_id: link) if link.present? + CatalogItemBuilder.apply_stock(supplied_product&.catalogItems&.first, variant) end end diff --git a/engines/dfc_provider/spec/services/supplied_product_builder_spec.rb b/engines/dfc_provider/spec/services/supplied_product_builder_spec.rb index 6c72952ab51..9a732e155cc 100644 --- a/engines/dfc_provider/spec/services/supplied_product_builder_spec.rb +++ b/engines/dfc_provider/spec/services/supplied_product_builder_spec.rb @@ -147,11 +147,23 @@ value: 2, ), productType: product_type, + catalogItems: [catalog_item], ) end let(:product_type) { DfcLoader.connector.PRODUCT_TYPES.VEGETABLE.NON_LOCAL_VEGETABLE } + let(:catalog_item) { + DataFoodConsortium::Connector::CatalogItem.new( + nil, + # On-demand is expressed as negative stock. + # And some APIs send strings instead of numbers... + stockLimitation: "-1", + ) + } it "creates a new Spree::Product and variant" do + # We need this to save stock: + DefaultStockLocation.find_or_create + create(:taxon) expect(imported_variant).to be_a(Spree::Variant) @@ -169,6 +181,11 @@ expect(imported_product.name).to eq("Tomato") expect(imported_product.description).to eq("Awesome tomato") expect(imported_product.variant_unit).to eq("weight") + + # Stock can only be checked when persisted: + imported_product.save! + expect(imported_variant.on_demand).to eq true + expect(imported_variant.on_hand).to eq 0 end context "with spree_product_id supplied" do