From faa112c3aebaa0042410fe778d7c3275c247f296 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Aug 2023 13:21:02 +1000 Subject: [PATCH 01/14] Spec DFC SuppliedProduct#update with new Prototype I observed new data from the DFC Prototype. It now uses the DFC 1.8 ontology with the hasQuantity object. It now also uses PUT requests for updates because PATCH is not as well supported. Rails doesn't care though. I couldn't observe a request for the CatalogItem yet because the Prototype failed to send it. --- .../supplied_products_controller.rb | 3 +- .../files/patch_supplied_product.json | 85 -------------- .../fixtures/files/put_supplied_product.json | 105 ++++++++++++++++++ .../spec/requests/supplied_products_spec.rb | 2 +- swagger/dfc-v1.7/swagger.yaml | 36 ++++-- 5 files changed, 134 insertions(+), 97 deletions(-) delete mode 100644 engines/dfc_provider/spec/fixtures/files/patch_supplied_product.json create mode 100644 engines/dfc_provider/spec/fixtures/files/put_supplied_product.json diff --git a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb index e2da4c46b7..3dddc7cb6e 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb @@ -37,9 +37,8 @@ module DfcProvider description: dfc_request["dfc-b:description"], ) - # This input is DFC v1.6 currently sent by the DFC Prototype. variant.update!( - unit_value: dfc_request["dfc-b:quantity"], + unit_value: dfc_request["dfc-b:hasQuantity"]["dfc-b:value"], ) end diff --git a/engines/dfc_provider/spec/fixtures/files/patch_supplied_product.json b/engines/dfc_provider/spec/fixtures/files/patch_supplied_product.json deleted file mode 100644 index 86230c7e7a..0000000000 --- a/engines/dfc_provider/spec/fixtures/files/patch_supplied_product.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "@context": { - "rdfs": "http://www.w3.org/2000/01/rdf-schema#", - "skos": "http://www.w3.org/2004/02/skos/core#", - "dfc": "http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl#", - "dc": "http://purl.org/dc/elements/1.1/#", - "dfc-b": "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#", - "dfc-p": "http://static.datafoodconsortium.org/ontologies/DFC_ProductOntology.owl#", - "dfc-t": "http://static.datafoodconsortium.org/ontologies/DFC_TechnicalOntology.owl#", - "dfc-m": "http://static.datafoodconsortium.org/data/measures.rdf#", - "dfc-pt": "http://static.datafoodconsortium.org/data/productTypes.rdf#", - "dfc-f": "http://static.datafoodconsortium.org/data/facets.rdf#", - "dfc-p:hasUnit": { - "@type": "@id" - }, - "dfc-b:hasUnit": { - "@type": "@id" - }, - "dfc-b:hasQuantity": { - "@type": "@id" - }, - "dfc-p:hasType": { - "@type": "@id" - }, - "dfc-b:hasType": { - "@type": "@id" - }, - "dfc-b:references": { - "@type": "@id" - }, - "dfc-b:referencedBy": { - "@type": "@id" - }, - "dfc-b:offeres": { - "@type": "@id" - }, - "dfc-b:supplies": { - "@type": "@id" - }, - "dfc-b:defines": { - "@type": "@id" - }, - "dfc-b:affiliates": { - "@type": "@id" - }, - "dfc-b:manages": { - "@type": "@id" - }, - "dfc-b:offeredThrough": { - "@type": "@id" - }, - "dfc-b:hasBrand": { - "@type": "@id" - }, - "dfc-b:hasGeographicalOrigin": { - "@type": "@id" - }, - "dfc-b:hasClaim": { - "@type": "@id" - }, - "dfc-b:hasAllergenDimension": { - "@type": "@id" - }, - "dfc-b:hasNutrimentDimension": { - "@type": "@id" - }, - "dfc-b:hasPhysicalDimension": { - "@type": "@id" - }, - "dfc:owner": { - "@type": "@id" - }, - "dfc-t:hostedBy": { - "@type": "@id" - }, - "dfc-t:hasPivot": { - "@type": "@id" - }, - "dfc-t:represent": { - "@type": "@id" - } - }, - "dfc-b:description": "DFC-Pesto updated", - "dfc-b:quantity": 17 -} diff --git a/engines/dfc_provider/spec/fixtures/files/put_supplied_product.json b/engines/dfc_provider/spec/fixtures/files/put_supplied_product.json new file mode 100644 index 0000000000..cc081912bb --- /dev/null +++ b/engines/dfc_provider/spec/fixtures/files/put_supplied_product.json @@ -0,0 +1,105 @@ +{ + "@context": { + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "skos": "http://www.w3.org/2004/02/skos/core#", + "dfc": "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_FullModel.owl#", + "dc": "http://purl.org/dc/elements/1.1/#", + "dfc-b": "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl#", + "dfc-p": "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_ProductGlossary.owl#", + "dfc-t": "https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_TechnicalOntology.owl#", + "dfc-m": "https://github.com/datafoodconsortium/taxonomies/releases/latest/download/measures.rdf#", + "dfc-pt": "https://github.com/datafoodconsortium/taxonomies/releases/latest/download/productTypes.rdf#", + "dfc-f": "https://github.com/datafoodconsortium/taxonomies/releases/latest/download/facets.rdf#", + "ontosec": "http://www.semanticweb.org/ontologies/2008/11/OntologySecurity.owl#", + "dfc-p:hasUnit": { + "@type": "@id" + }, + "dfc-b:hasUnit": { + "@type": "@id" + }, + "dfc-b:hasQuantity": { + "@type": "@id" + }, + "dfc-p:hasType": { + "@type": "@id" + }, + "dfc-b:hasType": { + "@type": "@id" + }, + "dfc-b:references": { + "@type": "@id" + }, + "dfc-b:referencedBy": { + "@type": "@id" + }, + "dfc-b:offeres": { + "@type": "@id" + }, + "dfc-b:supplies": { + "@type": "@id" + }, + "dfc-b:defines": { + "@type": "@id" + }, + "dfc-b:affiliates": { + "@type": "@id" + }, + "dfc-b:hasCertification": { + "@type": "@id" + }, + "dfc-b:manages": { + "@type": "@id" + }, + "dfc-b:offeredThrough": { + "@type": "@id" + }, + "dfc-b:hasBrand": { + "@type": "@id" + }, + "dfc-b:hasGeographicalOrigin": { + "@type": "@id" + }, + "dfc-b:hasClaim": { + "@type": "@id" + }, + "dfc-b:hasAllergenDimension": { + "@type": "@id" + }, + "dfc-b:hasNutrientDimension": { + "@type": "@id" + }, + "dfc-b:hasPhysicalDimension": { + "@type": "@id" + }, + "dfc:owner": { + "@type": "@id" + }, + "dfc-t:hostedBy": { + "@type": "@id" + }, + "dfc-t:hasPivot": { + "@type": "@id" + }, + "dfc-t:represent": { + "@type": "@id" + } + }, + "@id": "https://staging.coopcircuits.fr/api/dfc-v1.7/enterprises/2731/supplied_products/56790", + "@type": "dfc-b:SuppliedProduct", + "dfc-b:alcoholPercentage": 0, + "dfc-b:description": "DFC-Pesto updated", + "dfc-b:hasQuantity": { + "@type": "dfc-b:QuantitativeValue", + "dfc-b:hasUnit": "dfc-m:Piece", + "dfc-b:value": 17 + }, + "dfc-b:hasType": "dfc-pt:non-local-vegetable", + "dfc-b:lifetime": "", + "dfc-b:name": "Pesto novo", + "dfc-b:totalTheoreticalStock": 0, + "dfc-b:usageOrStorageCondition": "", + "dfc:owner": "http://proto.datafoodconsortium.org:3000/ldp/user/64c1d30351ecb4367037a9f6", + "dfc-b:hasPhysicalCharacteristic": [], + "dfc-b:hasNutrientCharacteristic": [], + "dfc-b:hasAllergenCharacteristic": [] +} diff --git a/engines/dfc_provider/spec/requests/supplied_products_spec.rb b/engines/dfc_provider/spec/requests/supplied_products_spec.rb index 689487bddb..23d5a96117 100644 --- a/engines/dfc_provider/spec/requests/supplied_products_spec.rb +++ b/engines/dfc_provider/spec/requests/supplied_products_spec.rb @@ -128,7 +128,7 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc-v1.7/swagger.yaml consumes "application/json" parameter name: :supplied_product, in: :body, schema: { - example: ExampleJson.read("patch_supplied_product") + example: ExampleJson.read("put_supplied_product") } let(:id) { variant.id } diff --git a/swagger/dfc-v1.7/swagger.yaml b/swagger/dfc-v1.7/swagger.yaml index 9ca116cf4f..8ef4ceba5d 100644 --- a/swagger/dfc-v1.7/swagger.yaml +++ b/swagger/dfc-v1.7/swagger.yaml @@ -412,14 +412,15 @@ paths: "@context": rdfs: http://www.w3.org/2000/01/rdf-schema# skos: http://www.w3.org/2004/02/skos/core# - dfc: http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl# + dfc: https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_FullModel.owl# dc: http://purl.org/dc/elements/1.1/# - dfc-b: http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl# - dfc-p: http://static.datafoodconsortium.org/ontologies/DFC_ProductOntology.owl# - dfc-t: http://static.datafoodconsortium.org/ontologies/DFC_TechnicalOntology.owl# - dfc-m: http://static.datafoodconsortium.org/data/measures.rdf# - dfc-pt: http://static.datafoodconsortium.org/data/productTypes.rdf# - dfc-f: http://static.datafoodconsortium.org/data/facets.rdf# + dfc-b: https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_BusinessOntology.owl# + dfc-p: https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_ProductGlossary.owl# + dfc-t: https://github.com/datafoodconsortium/ontology/releases/latest/download/DFC_TechnicalOntology.owl# + dfc-m: https://github.com/datafoodconsortium/taxonomies/releases/latest/download/measures.rdf# + dfc-pt: https://github.com/datafoodconsortium/taxonomies/releases/latest/download/productTypes.rdf# + dfc-f: https://github.com/datafoodconsortium/taxonomies/releases/latest/download/facets.rdf# + ontosec: http://www.semanticweb.org/ontologies/2008/11/OntologySecurity.owl# dfc-p:hasUnit: "@type": "@id" dfc-b:hasUnit: @@ -442,6 +443,8 @@ paths: "@type": "@id" dfc-b:affiliates: "@type": "@id" + dfc-b:hasCertification: + "@type": "@id" dfc-b:manages: "@type": "@id" dfc-b:offeredThrough: @@ -454,7 +457,7 @@ paths: "@type": "@id" dfc-b:hasAllergenDimension: "@type": "@id" - dfc-b:hasNutrimentDimension: + dfc-b:hasNutrientDimension: "@type": "@id" dfc-b:hasPhysicalDimension: "@type": "@id" @@ -466,7 +469,22 @@ paths: "@type": "@id" dfc-t:represent: "@type": "@id" + "@id": https://staging.coopcircuits.fr/api/dfc-v1.7/enterprises/2731/supplied_products/56790 + "@type": dfc-b:SuppliedProduct + dfc-b:alcoholPercentage: 0 dfc-b:description: DFC-Pesto updated - dfc-b:quantity: 17 + dfc-b:hasQuantity: + "@type": dfc-b:QuantitativeValue + dfc-b:hasUnit: dfc-m:Piece + dfc-b:value: 17 + dfc-b:hasType: dfc-pt:non-local-vegetable + dfc-b:lifetime: '' + dfc-b:name: Pesto novo + dfc-b:totalTheoreticalStock: 0 + dfc-b:usageOrStorageCondition: '' + dfc:owner: http://proto.datafoodconsortium.org:3000/ldp/user/64c1d30351ecb4367037a9f6 + dfc-b:hasPhysicalCharacteristic: [] + dfc-b:hasNutrientCharacteristic: [] + dfc-b:hasAllergenCharacteristic: [] servers: - url: "/" From 9ab75e086a11b7698fb7f8c2a356c221c9f56587 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Aug 2023 13:40:37 +1000 Subject: [PATCH 02/14] Use DFC Connector for SuppliedProduct update --- .../dfc_provider/supplied_products_controller.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb index 3dddc7cb6e..d68822d6b6 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb @@ -30,15 +30,16 @@ module DfcProvider end def update - dfc_request = JSON.parse(request.body.read) - return unless dfc_request.key?("dfc-b:description") + supplied_product = import&.first + + return head :bad_request unless supplied_product variant.product.update!( - description: dfc_request["dfc-b:description"], + description: supplied_product.description, ) variant.update!( - unit_value: dfc_request["dfc-b:hasQuantity"]["dfc-b:value"], + unit_value: supplied_product.quantity.value, ) end From 96b79bce2d2fb51a41caa503fd72947cdf848171 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Aug 2023 13:58:37 +1000 Subject: [PATCH 03/14] Encapsulate DFC-OFN data model bridge Re-uses existing code and takes knowledge out of the controller. --- .../dfc_provider/supplied_products_controller.rb | 9 +++------ .../app/services/supplied_product_builder.rb | 10 ++++++++++ .../spec/requests/supplied_products_spec.rb | 1 + 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb index d68822d6b6..8f7af81e00 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/supplied_products_controller.rb @@ -34,13 +34,10 @@ module DfcProvider return head :bad_request unless supplied_product - variant.product.update!( - description: supplied_product.description, - ) + SuppliedProductBuilder.apply(supplied_product, variant) - variant.update!( - unit_value: supplied_product.quantity.value, - ) + variant.product.save! + variant.save! end private diff --git a/engines/dfc_provider/app/services/supplied_product_builder.rb b/engines/dfc_provider/app/services/supplied_product_builder.rb index 02c8f3e00a..fe036dcfb1 100644 --- a/engines/dfc_provider/app/services/supplied_product_builder.rb +++ b/engines/dfc_provider/app/services/supplied_product_builder.rb @@ -26,4 +26,14 @@ class SuppliedProductBuilder < DfcBuilder QuantitativeValueBuilder.apply(supplied_product.quantity, product) end end + + def self.apply(supplied_product, variant) + variant.product.assign_attributes( + name: supplied_product.name, + description: supplied_product.description, + ) + + QuantitativeValueBuilder.apply(supplied_product.quantity, variant.product) + variant.unit_value = variant.product.unit_value + end end diff --git a/engines/dfc_provider/spec/requests/supplied_products_spec.rb b/engines/dfc_provider/spec/requests/supplied_products_spec.rb index 23d5a96117..e3dde17838 100644 --- a/engines/dfc_provider/spec/requests/supplied_products_spec.rb +++ b/engines/dfc_provider/spec/requests/supplied_products_spec.rb @@ -148,6 +148,7 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc-v1.7/swagger.yaml submit_request(example.metadata) variant.reload }.to change { variant.description }.to("DFC-Pesto updated") + .and change { variant.name }.to("Pesto novo") .and change { variant.unit_value }.to(17) end end From 996f3bb2353a24f687b983c53cff27a64749688c Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 14:36:53 +1000 Subject: [PATCH 04/14] Spec current quantity unit conversion --- .../quantitative_value_builder_spec.rb | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index b7d003a0ed..e36d34123b 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -43,4 +43,37 @@ describe QuantitativeValueBuilder do expect(quantity.unit.semanticId).to eq "dfc-m:Piece" end end + + describe ".apply" do + let(:quantity_unit) { DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT } + let(:product) { Spree::Product.new } + + it "uses items for anything unknown" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.JAR, + value: 3, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "items" + expect(product.variant_unit_name).to eq "items" + expect(product.variant_unit_scale).to eq 1 + expect(product.unit_value).to eq 3 + end + + it "knows metric units" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.LITRE, + value: 2, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "volume" + expect(product.variant_unit_name).to eq "liter" + expect(product.variant_unit_scale).to eq 1 + expect(product.unit_value).to eq 2 + end + end end From 5a8d95c4433551f3c0b60414595c37b41129ea39 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 14:43:32 +1000 Subject: [PATCH 05/14] Import DFC kilogram --- .../services/quantitative_value_builder.rb | 22 ++++++++++++------- .../quantitative_value_builder_spec.rb | 14 ++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 8291b3c0b0..0004c80703 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -28,17 +28,23 @@ class QuantitativeValueBuilder < DfcBuilder end def self.apply(quantity, product) - product.variant_unit, product.variant_unit_name = + quantity_unit = DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT + + measure, unit_name, unit_scale = case quantity.unit - when DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT.LITRE - ["volume", "liter"] - when DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT.GRAM - ["weight", "gram"] + when quantity_unit.LITRE + ["volume", "liter", 1] + when quantity_unit.GRAM + ["weight", "gram", 1] + when quantity_unit.KILOGRAM + ["weight", "kg", 1_000] else - ["items", "items"] + ["items", "items", 1] end - product.variant_unit_scale = 1 - product.unit_value = quantity.value + product.variant_unit = measure + product.variant_unit_name = unit_name + product.variant_unit_scale = unit_scale + product.unit_value = quantity.value * unit_scale end end diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index e36d34123b..60528f0ae6 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -75,5 +75,19 @@ describe QuantitativeValueBuilder do expect(product.variant_unit_scale).to eq 1 expect(product.unit_value).to eq 2 end + + it "knows metric units with a scale in OFN" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.KILOGRAM, + value: 4, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "weight" + expect(product.variant_unit_name).to eq "kg" + expect(product.variant_unit_scale).to eq 1_000 + expect(product.unit_value).to eq 4_000 + end end end From 9ddf536fa33441989906064dbad2c6a24c0e5e95 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 14:47:36 +1000 Subject: [PATCH 06/14] Import DFC milligram --- .../app/services/quantitative_value_builder.rb | 2 ++ .../services/quantitative_value_builder_spec.rb | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 0004c80703..7013063062 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -34,6 +34,8 @@ class QuantitativeValueBuilder < DfcBuilder case quantity.unit when quantity_unit.LITRE ["volume", "liter", 1] + when quantity_unit.MILLIGRAM + ["weight", "mg", 0.001] when quantity_unit.GRAM ["weight", "gram", 1] when quantity_unit.KILOGRAM diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index 60528f0ae6..aa2f7a9142 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -89,5 +89,19 @@ describe QuantitativeValueBuilder do expect(product.variant_unit_scale).to eq 1_000 expect(product.unit_value).to eq 4_000 end + + it "knows metric units with a small scale" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.MILLIGRAM, + value: 5, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "weight" + expect(product.variant_unit_name).to eq "mg" + expect(product.variant_unit_scale).to eq 0.001 + expect(product.unit_value).to eq 0.005 + end end end From 43346e267178719e6ca06fe8ac27c7f742305dc4 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 16:35:25 +1000 Subject: [PATCH 07/14] Import imperial DFC units --- .../services/quantitative_value_builder.rb | 43 +++++++++++++++++++ .../quantitative_value_builder_spec.rb | 14 ++++++ 2 files changed, 57 insertions(+) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 7013063062..901c2bdad0 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -30,16 +30,59 @@ class QuantitativeValueBuilder < DfcBuilder def self.apply(quantity, product) quantity_unit = DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT + # Unimplemented measures + # + # The DFC knows lots of single piece measures like a tub. There are not + # listed here and automatically mapped to "item". The following is a list + # of measures we want or could implement. + # + # Length: + # + # :CENTIMETRE, + # :DECIMETRE, + # :METRE, + # :KILOMETRE, + # :INCH, + # + # Metric: + # + # :CENTILITRE, + # :DECILITRE, + # :MILLILITRE, + # :TONNE, + # + # Bundles: + # + # :_4PACK, + # :_6PACK, + # :DOZEN, + # :HALFDOZEN, + # :PAIR, + # + # Other: + # + # :PERCENT, measure, unit_name, unit_scale = case quantity.unit when quantity_unit.LITRE ["volume", "liter", 1] + when quantity_unit.CUP + # Interpreted as metric cup, not US legal cup. + # https://github.com/datafoodconsortium/taxonomies/issues/8 + ["volume", "cu", 0.25] + when quantity_unit.GALLON + ["volume", "gal", 4.54609] when quantity_unit.MILLIGRAM ["weight", "mg", 0.001] when quantity_unit.GRAM ["weight", "gram", 1] when quantity_unit.KILOGRAM ["weight", "kg", 1_000] + # Not part of the DFC yet: + # when quantity_unit.OUNCE + # ["weight", "oz", 28.349523125] + when quantity_unit.POUNDMASS + ["weight", "lb", 453.59237] else ["items", "items", 1] end diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index aa2f7a9142..bff2829c71 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -103,5 +103,19 @@ describe QuantitativeValueBuilder do expect(product.variant_unit_scale).to eq 0.001 expect(product.unit_value).to eq 0.005 end + + it "knows imperial units" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.POUNDMASS, + value: 10, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "weight" + expect(product.variant_unit_name).to eq "lb" + expect(product.variant_unit_scale).to eq 453.59237 + expect(product.unit_value).to eq 4_535.9237 + end end end From f09678309807fa5b085b03300d4c36c1e5d61a2e Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 16:42:10 +1000 Subject: [PATCH 08/14] Import all metric DFC units --- .../app/services/quantitative_value_builder.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 901c2bdad0..b8f793babe 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -44,13 +44,6 @@ class QuantitativeValueBuilder < DfcBuilder # :KILOMETRE, # :INCH, # - # Metric: - # - # :CENTILITRE, - # :DECILITRE, - # :MILLILITRE, - # :TONNE, - # # Bundles: # # :_4PACK, @@ -66,6 +59,12 @@ class QuantitativeValueBuilder < DfcBuilder case quantity.unit when quantity_unit.LITRE ["volume", "liter", 1] + when quantity_unit.MILLILITRE + ["volume", "ml", 0.001] + when quantity_unit.CENTILITRE + ["volume", "cl", 0.01] + when quantity_unit.DECILITRE + ["volume", "dl", 0.1] when quantity_unit.CUP # Interpreted as metric cup, not US legal cup. # https://github.com/datafoodconsortium/taxonomies/issues/8 @@ -78,6 +77,8 @@ class QuantitativeValueBuilder < DfcBuilder ["weight", "gram", 1] when quantity_unit.KILOGRAM ["weight", "kg", 1_000] + when quantity_unit.TONNE + ["weight", "kg", 1_000_000] # Not part of the DFC yet: # when quantity_unit.OUNCE # ["weight", "oz", 28.349523125] From f96ab7c4321f3de1031abe0a3c2b20c54cfa65b6 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 17:00:20 +1000 Subject: [PATCH 09/14] Import DFC bundle units like dozen or 6 pack --- .../services/quantitative_value_builder.rb | 24 ++++++++++++------- .../quantitative_value_builder_spec.rb | 14 +++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index b8f793babe..1186c1d6ef 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -36,7 +36,7 @@ class QuantitativeValueBuilder < DfcBuilder # listed here and automatically mapped to "item". The following is a list # of measures we want or could implement. # - # Length: + # Length is not represented in the OFN: # # :CENTIMETRE, # :DECIMETRE, @@ -44,14 +44,6 @@ class QuantitativeValueBuilder < DfcBuilder # :KILOMETRE, # :INCH, # - # Bundles: - # - # :_4PACK, - # :_6PACK, - # :DOZEN, - # :HALFDOZEN, - # :PAIR, - # # Other: # # :PERCENT, @@ -84,6 +76,20 @@ class QuantitativeValueBuilder < DfcBuilder # ["weight", "oz", 28.349523125] when quantity_unit.POUNDMASS ["weight", "lb", 453.59237] + when quantity_unit.PAIR + # Ambiguous. A pair of trousers is one. + # A pair of socks is technically two but people see it as one item. + # I can't think of a good food example. A pair of lemons? + # So maybe it's two then. + ["items", "pair", 2] + when quantity_unit._4PACK + ["items", "4 pack", 4] + when quantity_unit._6PACK + ["items", "6 pack", 6] + when quantity_unit.HALFDOZEN + ["items", "half dozen", 6] + when quantity_unit.DOZEN + ["items", "dozen", 12] else ["items", "items", 1] end diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index bff2829c71..ed9a4a09e3 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -117,5 +117,19 @@ describe QuantitativeValueBuilder do expect(product.variant_unit_scale).to eq 453.59237 expect(product.unit_value).to eq 4_535.9237 end + + it "knows customary units" do + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: quantity_unit.DOZEN, + value: 2, + ) + + builder.apply(quantity, product) + + expect(product.variant_unit).to eq "items" + expect(product.variant_unit_name).to eq "dozen" + expect(product.variant_unit_scale).to eq 12 + expect(product.unit_value).to eq 24 + end end end From 8114430248dc2ec97c44a1ad5770e5c653ab7c97 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 28 Aug 2023 17:12:18 +1000 Subject: [PATCH 10/14] Refactor DFC unit mapping for easier reading I also updated the comments. --- .../services/quantitative_value_builder.rb | 142 ++++++++++-------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 1186c1d6ef..5d7ac7e142 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -28,75 +28,87 @@ class QuantitativeValueBuilder < DfcBuilder end def self.apply(quantity, product) - quantity_unit = DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT - - # Unimplemented measures - # - # The DFC knows lots of single piece measures like a tub. There are not - # listed here and automatically mapped to "item". The following is a list - # of measures we want or could implement. - # - # Length is not represented in the OFN: - # - # :CENTIMETRE, - # :DECIMETRE, - # :METRE, - # :KILOMETRE, - # :INCH, - # - # Other: - # - # :PERCENT, - measure, unit_name, unit_scale = - case quantity.unit - when quantity_unit.LITRE - ["volume", "liter", 1] - when quantity_unit.MILLILITRE - ["volume", "ml", 0.001] - when quantity_unit.CENTILITRE - ["volume", "cl", 0.01] - when quantity_unit.DECILITRE - ["volume", "dl", 0.1] - when quantity_unit.CUP - # Interpreted as metric cup, not US legal cup. - # https://github.com/datafoodconsortium/taxonomies/issues/8 - ["volume", "cu", 0.25] - when quantity_unit.GALLON - ["volume", "gal", 4.54609] - when quantity_unit.MILLIGRAM - ["weight", "mg", 0.001] - when quantity_unit.GRAM - ["weight", "gram", 1] - when quantity_unit.KILOGRAM - ["weight", "kg", 1_000] - when quantity_unit.TONNE - ["weight", "kg", 1_000_000] - # Not part of the DFC yet: - # when quantity_unit.OUNCE - # ["weight", "oz", 28.349523125] - when quantity_unit.POUNDMASS - ["weight", "lb", 453.59237] - when quantity_unit.PAIR - # Ambiguous. A pair of trousers is one. - # A pair of socks is technically two but people see it as one item. - # I can't think of a good food example. A pair of lemons? - # So maybe it's two then. - ["items", "pair", 2] - when quantity_unit._4PACK - ["items", "4 pack", 4] - when quantity_unit._6PACK - ["items", "6 pack", 6] - when quantity_unit.HALFDOZEN - ["items", "half dozen", 6] - when quantity_unit.DOZEN - ["items", "dozen", 12] - else - ["items", "items", 1] - end + measure, unit_name, unit_scale = map_unit(quantity.unit) product.variant_unit = measure product.variant_unit_name = unit_name product.variant_unit_scale = unit_scale product.unit_value = quantity.value * unit_scale end + + # Map DFC units to OFN fields: + # + # - variant_unit + # - variant_unit_name + # - variant_unit_scale + # + # Unimplemented measures + # + # The DFC knows lots of single piece measures like a tub. There are not + # listed here and automatically mapped to "item". The following is a list + # of measures we want or could implement. + # + # Length is not represented in the OFN: + # + # :CENTIMETRE, + # :DECIMETRE, + # :METRE, + # :KILOMETRE, + # :INCH, + # + # Other: + # + # :PERCENT, + # + # This method is quite long and may be shortened with new DFC features: + # + # * https://github.com/datafoodconsortium/taxonomies/issues/7 + # * https://github.com/datafoodconsortium/connector-ruby/issues/18 + # + # Until then, we can ignore Rubocop metrics, IMO. + def self.map_unit(unit) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength + quantity_unit = DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT + + case unit + when quantity_unit.LITRE + ["volume", "liter", 1] + when quantity_unit.MILLILITRE + ["volume", "ml", 0.001] + when quantity_unit.CENTILITRE + ["volume", "cl", 0.01] + when quantity_unit.DECILITRE + ["volume", "dl", 0.1] + when quantity_unit.CUP + # Interpreted as metric cup, not US legal cup. + # https://github.com/datafoodconsortium/taxonomies/issues/8 + ["volume", "cu", 0.25] + when quantity_unit.GALLON + ["volume", "gal", 4.54609] + when quantity_unit.MILLIGRAM + ["weight", "mg", 0.001] + when quantity_unit.GRAM + ["weight", "gram", 1] + when quantity_unit.KILOGRAM + ["weight", "kg", 1_000] + when quantity_unit.TONNE + ["weight", "kg", 1_000_000] + # Not part of the DFC yet: + # when quantity_unit.OUNCE + # ["weight", "oz", 28.349523125] + when quantity_unit.POUNDMASS + ["weight", "lb", 453.59237] + when quantity_unit.PAIR + ["items", "pair", 2] + when quantity_unit._4PACK + ["items", "4 pack", 4] + when quantity_unit._6PACK + ["items", "6 pack", 6] + when quantity_unit.HALFDOZEN + ["items", "half dozen", 6] + when quantity_unit.DOZEN + ["items", "dozen", 12] + else + ["items", "items", 1] + end + end end From 50f7177a38ea1602d487aa11f6ce8aab02622ec3 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 31 Aug 2023 09:11:32 +1000 Subject: [PATCH 11/14] Use existing service to label weight&volume units We still have the scale stored in two places but in our current system that's part of a unit's "id". If the DFC adds that value to its standard then we can use it for lookup and don't need to repeat it. * https://github.com/datafoodconsortium/taxonomies/issues/7 --- app/services/weights_and_measures.rb | 17 ++++++++--- .../services/quantitative_value_builder.rb | 30 +++++++++++-------- .../quantitative_value_builder_spec.rb | 8 ++--- .../variant_units/option_value_namer_spec.rb | 4 +-- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb index c2bc8c313c..79da11cf52 100644 --- a/app/services/weights_and_measures.rb +++ b/app/services/weights_and_measures.rb @@ -24,16 +24,25 @@ class WeightsAndMeasures UNITS = { 'weight' => { + 0.001 => { 'name' => 'mg', 'system' => 'metric' }, 1.0 => { 'name' => 'g', 'system' => 'metric' }, - 28.35 => { 'name' => 'oz', 'system' => 'imperial' }, - 453.6 => { 'name' => 'lb', 'system' => 'imperial' }, 1000.0 => { 'name' => 'kg', 'system' => 'metric' }, - 1_000_000.0 => { 'name' => 'T', 'system' => 'metric' } + 1_000_000.0 => { 'name' => 'T', 'system' => 'metric' }, + + 28.349523125 => { 'name' => 'oz', 'system' => 'imperial' }, + 28.35 => { 'name' => 'oz', 'system' => 'imperial' }, + 453.59237 => { 'name' => 'lb', 'system' => 'imperial' }, + 453.6 => { 'name' => 'lb', 'system' => 'imperial' }, }, 'volume' => { 0.001 => { 'name' => 'mL', 'system' => 'metric' }, + 0.01 => { 'name' => 'cL', 'system' => 'metric' }, + 0.1 => { 'name' => 'dL', 'system' => 'metric' }, 1.0 => { 'name' => 'L', 'system' => 'metric' }, - 1000.0 => { 'name' => 'kL', 'system' => 'metric' } + 1000.0 => { 'name' => 'kL', 'system' => 'metric' }, + + 0.25 => { 'name' => 'cu', 'system' => 'imperial' }, + 4.54609 => { 'name' => 'gal', 'system' => 'imperial' }, } }.freeze diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 5d7ac7e142..9903aa5965 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -31,7 +31,7 @@ class QuantitativeValueBuilder < DfcBuilder measure, unit_name, unit_scale = map_unit(quantity.unit) product.variant_unit = measure - product.variant_unit_name = unit_name + product.variant_unit_name = unit_name if measure == "items" product.variant_unit_scale = unit_scale product.unit_value = quantity.value * unit_scale end @@ -69,34 +69,38 @@ class QuantitativeValueBuilder < DfcBuilder def self.map_unit(unit) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength quantity_unit = DfcLoader.connector.MEASURES.UNIT.QUANTITYUNIT + # The unit name is only set for items. The name is implied for weight and + # volume and filled in by `WeightsAndMeasures`. case unit when quantity_unit.LITRE - ["volume", "liter", 1] + ["volume", nil, 1] when quantity_unit.MILLILITRE - ["volume", "ml", 0.001] + ["volume", nil, 0.001] when quantity_unit.CENTILITRE - ["volume", "cl", 0.01] + ["volume", nil, 0.01] when quantity_unit.DECILITRE - ["volume", "dl", 0.1] + ["volume", nil, 0.1] when quantity_unit.CUP # Interpreted as metric cup, not US legal cup. # https://github.com/datafoodconsortium/taxonomies/issues/8 - ["volume", "cu", 0.25] + ["volume", nil, 0.25] when quantity_unit.GALLON - ["volume", "gal", 4.54609] + ["volume", nil, 4.54609] + when quantity_unit.MILLIGRAM - ["weight", "mg", 0.001] + ["weight", nil, 0.001] when quantity_unit.GRAM - ["weight", "gram", 1] + ["weight", nil, 1] when quantity_unit.KILOGRAM - ["weight", "kg", 1_000] + ["weight", nil, 1_000] when quantity_unit.TONNE - ["weight", "kg", 1_000_000] + ["weight", nil, 1_000_000] # Not part of the DFC yet: # when quantity_unit.OUNCE - # ["weight", "oz", 28.349523125] + # ["weight", nil, 28.349523125] when quantity_unit.POUNDMASS - ["weight", "lb", 453.59237] + ["weight", nil, 453.59237] + when quantity_unit.PAIR ["items", "pair", 2] when quantity_unit._4PACK diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index ed9a4a09e3..d09067f816 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -71,7 +71,7 @@ describe QuantitativeValueBuilder do builder.apply(quantity, product) expect(product.variant_unit).to eq "volume" - expect(product.variant_unit_name).to eq "liter" + expect(product.variant_unit_name).to eq nil expect(product.variant_unit_scale).to eq 1 expect(product.unit_value).to eq 2 end @@ -85,7 +85,7 @@ describe QuantitativeValueBuilder do builder.apply(quantity, product) expect(product.variant_unit).to eq "weight" - expect(product.variant_unit_name).to eq "kg" + expect(product.variant_unit_name).to eq nil expect(product.variant_unit_scale).to eq 1_000 expect(product.unit_value).to eq 4_000 end @@ -99,7 +99,7 @@ describe QuantitativeValueBuilder do builder.apply(quantity, product) expect(product.variant_unit).to eq "weight" - expect(product.variant_unit_name).to eq "mg" + expect(product.variant_unit_name).to eq nil expect(product.variant_unit_scale).to eq 0.001 expect(product.unit_value).to eq 0.005 end @@ -113,7 +113,7 @@ describe QuantitativeValueBuilder do builder.apply(quantity, product) expect(product.variant_unit).to eq "weight" - expect(product.variant_unit_name).to eq "lb" + expect(product.variant_unit_name).to eq nil expect(product.variant_unit_scale).to eq 453.59237 expect(product.unit_value).to eq 4_535.9237 end diff --git a/spec/services/variant_units/option_value_namer_spec.rb b/spec/services/variant_units/option_value_namer_spec.rb index a902d35306..cf9178c244 100644 --- a/spec/services/variant_units/option_value_namer_spec.rb +++ b/spec/services/variant_units/option_value_namer_spec.rb @@ -115,8 +115,8 @@ module VariantUnits p = double(:product, variant_unit: 'volume', variant_unit_scale: scale) allow(v).to receive(:product) { p } allow(p).to receive(:persisted?) { true } - allow(v).to receive(:unit_value) { 100 * scale } - expect(subject.send(:option_value_value_unit)).to eq [100, unit] + allow(v).to receive(:unit_value) { 3 * scale } + expect(subject.send(:option_value_value_unit)).to eq [3, unit] end end From 427d806b1386b664edb1f18a2b1cf98c69f8a2e2 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 31 Aug 2023 16:11:50 +1000 Subject: [PATCH 12/14] Remove ambiguous unit "cup" The DFC doesn't actually specify which cup it means. I don't expect anyone providing "cup" as unit to measure their produce and expect it to calculate as a regular volume. It can just be seen as items. --- app/services/weights_and_measures.rb | 1 - .../dfc_provider/app/services/quantitative_value_builder.rb | 4 ---- 2 files changed, 5 deletions(-) diff --git a/app/services/weights_and_measures.rb b/app/services/weights_and_measures.rb index 79da11cf52..ada5523e22 100644 --- a/app/services/weights_and_measures.rb +++ b/app/services/weights_and_measures.rb @@ -41,7 +41,6 @@ class WeightsAndMeasures 1.0 => { 'name' => 'L', 'system' => 'metric' }, 1000.0 => { 'name' => 'kL', 'system' => 'metric' }, - 0.25 => { 'name' => 'cu', 'system' => 'imperial' }, 4.54609 => { 'name' => 'gal', 'system' => 'imperial' }, } }.freeze diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 9903aa5965..0ddd47cea1 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -80,10 +80,6 @@ class QuantitativeValueBuilder < DfcBuilder ["volume", nil, 0.01] when quantity_unit.DECILITRE ["volume", nil, 0.1] - when quantity_unit.CUP - # Interpreted as metric cup, not US legal cup. - # https://github.com/datafoodconsortium/taxonomies/issues/8 - ["volume", nil, 0.25] when quantity_unit.GALLON ["volume", nil, 4.54609] From 514b8fa6ab71a000e145904c3d5d6f34f4da66f8 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 31 Aug 2023 16:27:55 +1000 Subject: [PATCH 13/14] Import DFC unit labels like bunch and jar --- .../dfc_provider/app/services/quantitative_value_builder.rb | 5 ++++- .../spec/services/quantitative_value_builder_spec.rb | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 0ddd47cea1..3de24eb6ea 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -108,7 +108,10 @@ class QuantitativeValueBuilder < DfcBuilder when quantity_unit.DOZEN ["items", "dozen", 12] else - ["items", "items", 1] + # Labels may be provided one day: + # https://github.com/datafoodconsortium/connector-ruby/issues/18 + label = unit.semanticId.split("#").last || "items" + ["items", label, 1] end end end diff --git a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb index d09067f816..bd744fa568 100644 --- a/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb +++ b/engines/dfc_provider/spec/services/quantitative_value_builder_spec.rb @@ -57,7 +57,7 @@ describe QuantitativeValueBuilder do builder.apply(quantity, product) expect(product.variant_unit).to eq "items" - expect(product.variant_unit_name).to eq "items" + expect(product.variant_unit_name).to eq "Jar" expect(product.variant_unit_scale).to eq 1 expect(product.unit_value).to eq 3 end From 57b4f615e8e6bef099563fde6947d86fbf786f47 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 31 Aug 2023 17:06:20 +1000 Subject: [PATCH 14/14] Fix DFC context in spec example --- .../dfc_provider/app/services/quantitative_value_builder.rb | 2 +- engines/dfc_provider/spec/requests/supplied_products_spec.rb | 3 +++ swagger/dfc-v1.7/swagger.yaml | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/engines/dfc_provider/app/services/quantitative_value_builder.rb b/engines/dfc_provider/app/services/quantitative_value_builder.rb index 3de24eb6ea..b3328713e3 100644 --- a/engines/dfc_provider/app/services/quantitative_value_builder.rb +++ b/engines/dfc_provider/app/services/quantitative_value_builder.rb @@ -110,7 +110,7 @@ class QuantitativeValueBuilder < DfcBuilder else # Labels may be provided one day: # https://github.com/datafoodconsortium/connector-ruby/issues/18 - label = unit.semanticId.split("#").last || "items" + label = unit.try(:semanticId)&.split("#")&.last || "items" ["items", label, 1] end end diff --git a/engines/dfc_provider/spec/requests/supplied_products_spec.rb b/engines/dfc_provider/spec/requests/supplied_products_spec.rb index e3dde17838..c4d9ef1d6e 100644 --- a/engines/dfc_provider/spec/requests/supplied_products_spec.rb +++ b/engines/dfc_provider/spec/requests/supplied_products_spec.rb @@ -32,6 +32,9 @@ describe "SuppliedProducts", type: :request, swagger_doc: "dfc-v1.7/swagger.yaml 'dfc-b': "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#", 'dfc-m': "http://static.datafoodconsortium.org/data/measures.rdf#", 'dfc-pt': "http://static.datafoodconsortium.org/data/productTypes.rdf#", + 'dfc-b:hasUnit': { + '@type': "@id" + }, }, '@id': "http://test.host/api/dfc-v1.7/enterprises/6201/supplied_products/0", '@type': "dfc-b:SuppliedProduct", diff --git a/swagger/dfc-v1.7/swagger.yaml b/swagger/dfc-v1.7/swagger.yaml index 8ef4ceba5d..431be36edb 100644 --- a/swagger/dfc-v1.7/swagger.yaml +++ b/swagger/dfc-v1.7/swagger.yaml @@ -330,7 +330,7 @@ paths: dfc-b:hasType: http://static.datafoodconsortium.org/data/productTypes.rdf#non-local-vegetable dfc-b:hasQuantity: "@type": dfc-b:QuantitativeValue - dfc-b:hasUnit: dfc-m:Piece + dfc-b:hasUnit: dfc-m:Gram dfc-b:value: 3.0 dfc-b:alcoholPercentage: 0.0 dfc-b:lifetime: '' @@ -345,6 +345,8 @@ paths: dfc-b: http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl# dfc-m: http://static.datafoodconsortium.org/data/measures.rdf# dfc-pt: http://static.datafoodconsortium.org/data/productTypes.rdf# + dfc-b:hasUnit: + "@type": "@id" "@id": http://test.host/api/dfc-v1.7/enterprises/6201/supplied_products/0 "@type": dfc-b:SuppliedProduct dfc-b:name: Apple