Import variants for the same product group

When importing another catalog, it's probably referring to external
product groups. Storing the external link allows us to group several
variants and replicate the same structure within OFN.
This commit is contained in:
Maikel Linke
2025-01-23 16:44:40 +11:00
parent c1e0c6ed34
commit 516759062f
3 changed files with 49 additions and 7 deletions

View File

@@ -36,6 +36,7 @@ module Spree
searchable_scopes :active, :with_properties
has_one :image, class_name: "Spree::Image", as: :viewable, dependent: :destroy
has_one :semantic_link, as: :subject, dependent: :delete
has_many :product_properties, dependent: :destroy
has_many :properties, through: :product_properties

View File

@@ -44,6 +44,7 @@ class SuppliedProductImporter < DfcBuilder
# We will remove the old methods at some point.
def self.referenced_spree_product(supplied_product, supplier)
spree_product(supplied_product, supplier) ||
spree_product_linked(supplied_product, supplier) ||
spree_product_from_uri(supplied_product, supplier) ||
spree_product_from_id(supplied_product, supplier)
end
@@ -51,15 +52,28 @@ class SuppliedProductImporter < DfcBuilder
def self.spree_product(supplied_product, supplier)
supplied_product.isVariantOf.lazy.map do |group|
group_id = group.semanticId
route = Rails.application.routes.recognize_path(group_id)
id = begin
route = Rails.application.routes.recognize_path(group_id)
# Check that the given URI points to us:
next if group_id != urls.enterprise_technical_product_url(route)
# Check that the given URI points to us:
next if group_id != urls.enterprise_technical_product_url(route)
supplier.supplied_products.find_by(id: route[:id])
route[:id]
rescue ActionController::RoutingError
next
end
supplier.supplied_products.find_by(id:)
end.compact.first
end
def self.spree_product_linked(supplied_product, supplier)
semantic_ids = supplied_product.isVariantOf.map(&:semanticId)
supplier.supplied_products.includes(:semantic_link)
.where(semantic_link: { semantic_id: semantic_ids })
.first
end
def self.spree_product_from_uri(supplied_product, supplier)
uri = supplied_product.spree_product_uri
return if uri.blank?
@@ -86,6 +100,7 @@ class SuppliedProductImporter < DfcBuilder
supplier_id: supplier.id,
primary_taxon_id: taxon(supplied_product).id,
image: ImageBuilder.import(supplied_product.image),
semantic_link: semantic_link(supplied_product),
).tap do |product|
QuantitativeValueBuilder.apply(supplied_product.quantity, product)
product.ensure_standard_variant
@@ -105,9 +120,14 @@ class SuppliedProductImporter < DfcBuilder
OfferBuilder.apply(offer, variant)
end
def self.semantic_link(supplied_product)
semantic_id = supplied_product.isVariantOf.first&.semanticId
SemanticLink.new(semantic_id:) if semantic_id.present?
end
def self.taxon(supplied_product)
ProductTypeImporter.taxon(supplied_product.productType)
end
private_class_method :taxon
end

View File

@@ -186,7 +186,7 @@ RSpec.describe SuppliedProductImporter do
expect(imported_variant.on_hand).to eq 0
end
context "with spree_product_id supplied" do
context "linked to product group" do
let(:imported_variant) { importer.import_variant(supplied_product, supplier) }
let(:supplied_product) do
@@ -229,7 +229,13 @@ RSpec.describe SuppliedProductImporter do
value: 2,
),
productType: product_type,
spree_product_uri: "http://another.host/api/dfc/enterprises/10/supplied_products/50"
spree_product_uri: "http://another.host/api/dfc/enterprises/10/supplied_products/50",
isVariantOf: [technical_product],
)
end
let(:technical_product) do
DataFoodConsortium::Connector::TechnicalProduct.new(
"http://test.host/api/dfc/enterprises/7/technical_products/6"
)
end
@@ -243,6 +249,8 @@ RSpec.describe SuppliedProductImporter do
expect(imported_product.name).to eq("Tomato")
expect(imported_product.description).to eq("Awesome tomato")
expect(imported_product.variant_unit).to eq("weight")
expect(imported_product.semantic_link.semantic_id)
.to eq "http://test.host/api/dfc/enterprises/7/technical_products/6"
end
end
end
@@ -270,6 +278,19 @@ RSpec.describe SuppliedProductImporter do
expect(result).to eq spree_product
end
it "returns a product referenced by external URI" do
variant.save!
supplied_product.isVariantOf <<
DataFoodConsortium::Connector::TechnicalProduct.new(
"http://example.net/product_group"
)
SemanticLink.create!(
subject: spree_product,
semantic_id: "http://example.net/product_group",
)
expect(result).to eq spree_product
end
it "returns a product referenced by URI" do
variant.save!
supplied_product.spree_product_uri =