From 7826c7ae6414593c278239cf154e6acac85c0a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bournhonesque?= Date: Wed, 16 Aug 2023 14:31:47 +0200 Subject: [PATCH 1/3] docs: fix wrong command in docs --- docs/dev/how-to-write-and-run-tests.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/how-to-write-and-run-tests.md b/docs/dev/how-to-write-and-run-tests.md index db70aed63cded..136e93f19eebf 100644 --- a/docs/dev/how-to-write-and-run-tests.md +++ b/docs/dev/how-to-write-and-run-tests.md @@ -88,7 +88,7 @@ If you made change that impact stored expected results, you can use: * or to generate expected results for a single test (here for integration test, `test-unit` otherwise) ```bash - make test-int="filename.t --update-expected results" + make test-int test="filename.t --update-expected-results" ``` If you re-generate test results, be sure to look carefully that the changes your commit are expected changes. From 5950e9d7f34d3675dd8bde82b5a2106730c36216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bournhonesque?= Date: Wed, 16 Aug 2023 14:32:04 +0200 Subject: [PATCH 2/3] fix: fix undefined warning in APITest.pm --- lib/ProductOpener/APITest.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ProductOpener/APITest.pm b/lib/ProductOpener/APITest.pm index b282a7870753e..33891f20ccbaf 100644 --- a/lib/ProductOpener/APITest.pm +++ b/lib/ProductOpener/APITest.pm @@ -515,7 +515,7 @@ sub execute_api_tests ($file, $tests_ref, $ua = undef) { my $response_content = $response->decoded_content; - if ($test_ref->{expected_type} eq 'text') { + if ((defined $test_ref->{expected_type}) and ($test_ref->{expected_type} eq 'text')) { # Check that the text file is the same as expected (useful for checking dynamic robots.txt) is( compare_file_to_expected_results( From 1c914dc58f14a3f0947f88957ae722f333af1a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Bournhonesque?= Date: Wed, 16 Aug 2023 14:35:14 +0200 Subject: [PATCH 3/3] fix: use ingredient list if lang != lc to parse ingredients --- docs/api/ref/schemas/product_ingredients.yaml | 7 + lib/ProductOpener/Display.pm | 5 +- lib/ProductOpener/Ingredients.pm | 417 +++++++------- lib/ProductOpener/KnowledgePanels.pm | 2 +- lib/ProductOpener/Products.pm | 2 + .../get-existing-product.json | 1 + .../get-fields-all-knowledge-panels.json | 3 +- .../api_v2_product_read/get-fields-all.json | 1 + ...attribute-groups-all-knowledge-panels.json | 3 +- .../api_v2_product_read/get-fields-raw.json | 1 + .../get-knowledge-panels-fr.json | 2 +- .../get-knowledge-panels.json | 2 +- .../get-product-auth-good-password.json | 1 + .../api_v2_product_write/get-product.json | 1 + .../get-existing-product.json | 1 + .../get-fields-all-knowledge-panels.json | 3 +- .../api_v3_product_read/get-fields-all.json | 1 + ...attribute-groups-all-knowledge-panels.json | 3 +- .../api_v3_product_read/get-fields-raw.json | 1 + .../get-knowledge-panels-fr.json | 2 +- .../get-knowledge-panels.json | 2 +- .../patch-request-fields-all.json | 1 + .../products/3250390017165.json | 1 + .../products/3250390020745.json | 1 + .../products/3250390020806.json | 1 + .../products/3250390020998.json | 1 + .../products/3250390021001.json | 1 + .../products/3250390021469.json | 1 + .../products/3250390021544.json | 1 + .../products/3250390021568.json | 1 + .../products/3250390021926.json | 1 + .../products/3250390024781.json | 1 + .../products/3250390024804.json | 1 + .../products/3250390024842.json | 1 + .../products/3250390024866.json | 1 + .../products/3250390025399.json | 1 + .../products/3250390025863.json | 1 + .../products/3250390026044.json | 1 + .../products/3250390026648.json | 1 + .../products/3250390026754.json | 1 + .../test/products/3270190128403.json | 1 + .../test/products/4270190128403.json | 119 +++- .../test/products/5270190128403.json | 1 + .../test/products/7270190128403.json | 1 + .../data-quality.json | 2 +- .../no-data-quality.json | 2 +- .../3003004006001.json | 1 + .../3003004006002.json | 1 + .../3003004006003.json | 1 + .../3003004006004.json | 1 + .../3003004006005.json | 1 + .../3003004006006.json | 1 + .../3003004006007.json | 1 + .../import_csv_file/test/2003004006001.json | 1 + .../import_csv_file/test/2003004006002.json | 1 + .../import_csv_file/test/2003004006003.json | 1 + .../import_csv_file/test/2003004006004.json | 1 + .../import_csv_file/test/2003004006005.json | 1 + .../import_csv_file/test/2003004006006.json | 1 + .../import_csv_file/test/2003004006007.json | 1 + ...ed-protected-product-api-v2-moderator.json | 1 + .../get-edited-protected-product-api-v2.json | 1 + ...-protected-product-web-form-moderator.json | 1 + ...get-edited-protected-product-web-form.json | 1 + ...get-edited-unprotected-product-api-v2.json | 1 + ...t-edited-unprotected-product-web-form.json | 1 + .../search_v1/search-no-filter.json | 524 ++++++++++++------ ...ies-without-ingredients-from-palm-oil.json | 218 +++++--- ...rch-without-ingredients-from-palm-oil.json | 514 +++++++++++------ .../attributes/en-attributes.json | 1 + .../en-ecoscore-score-at-20-threshold.json | 1 + .../attributes/en-maybe-vegan.json | 1 + .../attributes/en-no-ingredients.json | 1 + .../attributes/en-nova-groups-markers.json | 1 + .../attributes/en-nutriscore.json | 1 + .../attributes/en-unknown-ingredients.json | 1 + .../attributes/fr-palm-kernel-fat.json | 1 + .../attributes/fr-palm-oil-free.json | 1 + .../attributes/fr-palm-oil.json | 1 + .../attributes/fr-vegetable-oils.json | 1 + 80 files changed, 1281 insertions(+), 612 deletions(-) diff --git a/docs/api/ref/schemas/product_ingredients.yaml b/docs/api/ref/schemas/product_ingredients.yaml index b885d5a69e945..b3705886a54e6 100644 --- a/docs/api/ref/schemas/product_ingredients.yaml +++ b/docs/api/ref/schemas/product_ingredients.yaml @@ -70,6 +70,13 @@ properties: type: array items: type: string + ingredients_lc: + type: string + description: | + Language that was used to parse the ingredient list. If `ingredients_text` is available + for the product main language (`lang`), `ingredients_lc=lang`, otherwise we look at + `ingredients_text` fields for other languages and set `ingredients_lc` to the first + non-empty `ingredient_text`. ingredients_text: type: string description: | diff --git a/lib/ProductOpener/Display.pm b/lib/ProductOpener/Display.pm index 51eae3ff59381..e7eb6a1a64318 100644 --- a/lib/ProductOpener/Display.pm +++ b/lib/ProductOpener/Display.pm @@ -7828,7 +7828,7 @@ JS # try to display ingredients in the local language if available my $ingredients_text = $product_ref->{ingredients_text}; - my $ingredients_text_lang = $product_ref->{lc}; + my $ingredients_text_lang = $product_ref->{ingredients_lc}; if (defined $product_ref->{ingredients_text_with_allergens}) { $ingredients_text = $product_ref->{ingredients_text_with_allergens}; @@ -11039,7 +11039,8 @@ sub data_to_display_ingredients_analysis_details ($product_ref) { my $result_data_ref = {}; - my $ingredients_text = ""; + my $ingredients_text_lc = $product_ref->{ingredients_lc}; + my $ingredients_text = "$ingredients_text_lc: "; my $ingredients_list = ""; display_nested_list_of_ingredients($product_ref->{ingredients}, \$ingredients_text, \$ingredients_list); diff --git a/lib/ProductOpener/Ingredients.pm b/lib/ProductOpener/Ingredients.pm index 3bb1071b902c1..18e7eeba34585 100644 --- a/lib/ProductOpener/Ingredients.pm +++ b/lib/ProductOpener/Ingredients.pm @@ -63,6 +63,7 @@ BEGIN { &clean_ingredients_text_for_lang &cut_ingredients_text_for_lang &clean_ingredients_text + &select_ingredients_lc &detect_allergens_from_text @@ -858,7 +859,7 @@ Array of specific ingredients. sub add_specific_ingredients_from_labels ($product_ref) { - my $product_lc = $product_ref->{lc}; + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; if (defined $product_ref->{labels_tags}) { foreach my $labelid (@{$product_ref->{labels_tags}}) { @@ -918,7 +919,7 @@ Array of specific ingredients. sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) { - my $product_lc = $product_ref->{lc}; + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; # Go through the ingredient lists multiple times # as long as we have one match @@ -938,7 +939,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) # Regexps should match until we reach a . ; or the end of the text - if ($product_lc eq "en") { + if ($ingredients_lc eq "en") { # examples: # Total Milk Content 73%. @@ -957,7 +958,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) } # Origin of the milk: United Kingdom - elsif (match_origin_of_the_ingredient_origin($product_lc, \$text, $matched_ingredient_ref)) { + elsif (match_origin_of_the_ingredient_origin($ingredients_lc, \$text, $matched_ingredient_ref)) { $origins = $matched_ingredient_ref->{origins}; $ingredient = $matched_ingredient_ref->{ingredient}; $matched_text = $matched_ingredient_ref->{matched_text}; @@ -965,7 +966,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) $ingredient =~ s/\s+$//; } } - elsif ($product_lc eq "fr") { + elsif ($ingredients_lc eq "fr") { # examples: # Teneur en lait 25% minimum. @@ -1003,7 +1004,7 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) } # Origine du Cacao: Pérou - elsif (match_origin_of_the_ingredient_origin($product_lc, \$text, $matched_ingredient_ref)) { + elsif (match_origin_of_the_ingredient_origin($ingredients_lc, \$text, $matched_ingredient_ref)) { $origins = $matched_ingredient_ref->{origins}; $ingredient = $matched_ingredient_ref->{ingredient}; $matched_text = $matched_ingredient_ref->{matched_text}; @@ -1016,7 +1017,8 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) # If we found an ingredient, save it in specific_ingredients if (defined $ingredient) { my $ingredient_id - = get_taxonomyid($product_lc, canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient)); + = get_taxonomyid($ingredients_lc, + canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient)); $matched_text =~ s/^\s+//; @@ -1026,11 +1028,12 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) text => $matched_text, }; - my $and_or = $and_or{$product_lc}; + my $and_or = $and_or{$ingredients_lc}; defined $percent and $specific_ingredients_ref->{percent} = $percent + 0; defined $origins and $specific_ingredients_ref->{origins} - = join(",", map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} split(/,|$and_or/, $origins)); + = join(",", + map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,|$and_or/, $origins)); push @{$product_ref->{specific_ingredients}}, $specific_ingredients_ref; } @@ -1044,11 +1047,11 @@ sub parse_specific_ingredients_from_text ($product_ref, $text, $percent_regexp) # Regexps should match until we reach a . ; or the end of the text -sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) { +sub match_ingredient_origin ($ingredients_lc, $text_ref, $matched_ingredient_ref) { - my $origins_regexp = $origins_regexps{$product_lc}; - my $and_or = $and_or{$product_lc} || ','; - my $from = $from{$product_lc} || ':'; + my $origins_regexp = $origins_regexps{$ingredients_lc}; + my $and_or = $and_or{$ingredients_lc} || ','; + my $from = $from{$ingredients_lc} || ':'; # Strawberries: Spain, Italy and Portugal # Strawberries from Spain, Italy and Portugal @@ -1087,7 +1090,7 @@ sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) { not( exists_taxonomy_tag( "ingredients", - canonicalize_taxonomy_tag($product_lc, "ingredients", $matched_ingredient_ref->{ingredient}) + canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $matched_ingredient_ref->{ingredient}) ) ) ) @@ -1104,16 +1107,16 @@ sub match_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) { return 0; } -sub match_origin_of_the_ingredient_origin ($product_lc, $text_ref, $matched_ingredient_ref) { +sub match_origin_of_the_ingredient_origin ($ingredients_lc, $text_ref, $matched_ingredient_ref) { my %origin_of_the_regexp_in_lc = ( en => "(?:origin of (?:the )?)", fr => "(?:origine (?:de |du |de la |des |de l'))", ); - my $origin_of_the_regexp = $origin_of_the_regexp_in_lc{$product_lc} || $origin_of_the_regexp_in_lc{en}; - my $origins_regexp = $origins_regexps{$product_lc}; - my $and_or = $and_or{$product_lc} || ','; + my $origin_of_the_regexp = $origin_of_the_regexp_in_lc{$ingredients_lc} || $origin_of_the_regexp_in_lc{en}; + my $origins_regexp = $origins_regexps{$ingredients_lc}; + my $and_or = $and_or{$ingredients_lc} || ','; # Origin of the milk: United Kingdom. if ( @@ -1167,7 +1170,7 @@ Array of specific ingredients. sub parse_origins_from_text ($product_ref, $text) { - my $product_lc = $product_ref->{lc}; + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; # Normalize single quotes $text =~ s/’/'/g; @@ -1186,12 +1189,13 @@ sub parse_origins_from_text ($product_ref, $text) { # Call match functions to look for different ways to specify origins etc. foreach my $match_function_ref (\&match_origin_of_the_ingredient_origin, \&match_ingredient_origin) { - if ($match_function_ref->($product_lc, \$text, $matched_ingredient_ref)) { + if ($match_function_ref->($ingredients_lc, \$text, $matched_ingredient_ref)) { my $matched_text = $matched_ingredient_ref->{matched_text}; my $ingredient = $matched_ingredient_ref->{ingredient}; my $ingredient_id - = get_taxonomyid($product_lc, canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient)); + = get_taxonomyid($ingredients_lc, + canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient)); # Remove extra spaces $ingredient =~ s/\s+$//; @@ -1204,9 +1208,9 @@ sub parse_origins_from_text ($product_ref, $text) { }; if (defined $matched_ingredient_ref->{origins}) { - my $and_or = $and_or{$product_lc}; + my $and_or = $and_or{$ingredients_lc}; $specific_ingredients_ref->{origins} = join(",", - map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} + map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,|$and_or/, $matched_ingredient_ref->{origins})); } @@ -1221,7 +1225,35 @@ sub parse_origins_from_text ($product_ref, $text) { return $text; } -=head2 parse_ingredients_text ( product_ref ) +=head2 select_ingredients_lc ($product_ref) + +Return the `ingredients_lc` field to save in $product_ref. + +This is the language that will be used to parse ingredients. We first check that ingredients_text_{lang} +exists and is non-empty for the product main language (`lc`), and return it if it does. +Otherwise we look at all languages defined in `languages_codes` for a non-empty `ingredients_text_lang`. + +=head3 Arguments + +=head4 $product_ref + +=cut + +sub select_ingredients_lc ($product_ref) { + if (defined $product_ref->{languages_codes}) { + # We sort the keys so that the order is deterministic + foreach my $language ($product_ref->{lc}, sort keys %{$product_ref->{languages_codes}}) { + if ( (defined $product_ref->{"ingredients_text_" . $language}) + and ($product_ref->{"ingredients_text_" . $language} ne "")) + { + return $language; + } + } + } + return $product_ref->{lc}; +} + +=head2 parse_ingredients_text ( $product_ref ) Parse the ingredients_text field to extract individual ingredients. @@ -1247,9 +1279,10 @@ sub parse_ingredients_text ($product_ref) { $log->debug("extracting ingredients from text", {text => $text}) if $log->is_debug(); - my $product_lc = $product_ref->{lc}; + # $product_ref->{ingredients_lc} is defined in extract_ingredients_from_text() + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; - $text = preparse_ingredients_text($product_lc, $text); + $text = preparse_ingredients_text($ingredients_lc, $text); $log->debug("preparsed ingredients from text", {text => $text}) if $log->is_debug(); @@ -1257,8 +1290,8 @@ sub parse_ingredients_text ($product_ref) { # jus de pomme, eau, sucre. Traces possibles de c\x{e9}leri, moutarde et gluten.", # -> jus de pomme, eau, sucre. Traces éventuelles : céleri, Traces éventuelles : moutarde, Traces éventuelles : gluten. - my $traces = $Lang{traces}{$product_lc}; - my $allergens = $Lang{allergens}{$product_lc}; + my $traces = $Lang{traces}{$ingredients_lc}; + my $allergens = $Lang{allergens}{$ingredients_lc}; $text =~ s/\b($traces|$allergens)\s?:\s?([^,\.]+)//ig; # unify newline feeds to \n @@ -1279,15 +1312,15 @@ sub parse_ingredients_text ($product_ref) { $text =~ s/(\d),(\d)/$1‚$2/g; - my $and = $and{$product_lc} || " and "; + my $and = $and{$ingredients_lc} || " and "; my $min_regexp = ""; - if (defined $min_regexp{$product_lc}) { - $min_regexp = $min_regexp{$product_lc}; + if (defined $min_regexp{$ingredients_lc}) { + $min_regexp = $min_regexp{$ingredients_lc}; } my $ignore_strings_after_percent = ""; - if (defined $ignore_strings_after_percent{$product_lc}) { - $ignore_strings_after_percent = $ignore_strings_after_percent{$product_lc}; + if (defined $ignore_strings_after_percent{$ingredients_lc}) { + $ignore_strings_after_percent = $ignore_strings_after_percent{$ingredients_lc}; } my $percent_regexp @@ -1396,7 +1429,7 @@ sub parse_ingredients_text ($product_ref) { # sel marin (France, Italie) # -> if we have origins, put "origins:" before if ( ($between =~ $separators) - and (exists_taxonomy_tag("origins", canonicalize_taxonomy_tag($product_lc, "origins", $`)))) + and (exists_taxonomy_tag("origins", canonicalize_taxonomy_tag($ingredients_lc, "origins", $`)))) { $between =~ s/^(.*?$separators)/origins:$1/; } @@ -1446,14 +1479,14 @@ sub parse_ingredients_text ($product_ref) { } else { $origin = join(",", - map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} + map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,/, $origin_string)); } } else { # origins: Fraise (France) - my $originid = canonicalize_taxonomy_tag($product_lc, "origins", $between); + my $originid = canonicalize_taxonomy_tag($ingredients_lc, "origins", $between); if (exists_taxonomy_tag("origins", $originid)) { $origin = $originid; $debug_ingredients @@ -1466,7 +1499,7 @@ sub parse_ingredients_text ($product_ref) { # Skip too short entries (1 or 2 letters) to avoid false positives elsif (length($between) >= 3) { - my $labelid = canonicalize_taxonomy_tag($product_lc, "labels", $between); + my $labelid = canonicalize_taxonomy_tag($ingredients_lc, "labels", $between); if (exists_taxonomy_tag("labels", $labelid)) { if (defined $labels) { $labels .= ", " . $labelid; @@ -1501,7 +1534,7 @@ sub parse_ingredients_text ($product_ref) { # processing method? my $processingid - = canonicalize_taxonomy_tag($product_lc, "ingredients_processing", + = canonicalize_taxonomy_tag($ingredients_lc, "ingredients_processing", $between); if (exists_taxonomy_tag("ingredients_processing", $processingid)) { if (defined $processing) { @@ -1578,7 +1611,7 @@ sub parse_ingredients_text ($product_ref) { $ingredient2 =~ s/\s$percent_regexp$//i; # check if the whole ingredient is an ingredient - my $canon_ingredient = canonicalize_taxonomy_tag($product_lc, "ingredients", $before); + my $canon_ingredient = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $before); $debug_ingredients and $log->debug( "ingredient contains 'and', checking if it exists", @@ -1588,8 +1621,8 @@ sub parse_ingredients_text ($product_ref) { if (not exists_taxonomy_tag("ingredients", $canon_ingredient)) { # otherwise check the 2 sub ingredients - my $canon_ingredient1 = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient1); - my $canon_ingredient2 = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient2); + my $canon_ingredient1 = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient1); + my $canon_ingredient2 = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient2); $debug_ingredients and $log->debug( "ingredient containing 'and' did not exist. 2 known ingredients?", @@ -1701,16 +1734,16 @@ sub parse_ingredients_text ($product_ref) { } else { $origin = join(",", - map {canonicalize_taxonomy_tag($product_lc, "origins", $_)} split(/,/, $origin_string)); + map {canonicalize_taxonomy_tag($ingredients_lc, "origins", $_)} split(/,/, $origin_string)); } } # Check if we have an ingredient + some specific labels like organic and fair-trade. # If we do, remove the label from the ingredient and add the label to labels - if (defined $labels_regexps{$product_lc}) { + if (defined $labels_regexps{$ingredients_lc}) { # start with uncomposed labels first, so that we decompose "fair-trade organic" into "fair-trade, organic" foreach my $labelid (reverse @labels) { - my $regexp = $labels_regexps{$product_lc}{$labelid}; + my $regexp = $labels_regexps{$ingredients_lc}{$labelid}; $debug_ingredients and $log->trace("checking labels regexps", {ingredient => $ingredient, labelid => $labelid, regexp => $regexp}) if $log->is_trace(); @@ -1740,7 +1773,7 @@ sub parse_ingredients_text ($product_ref) { $ingredient =~ s/^\s+//; $ingredient =~ s/\s+$//; - $ingredient_id = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient); + $ingredient_id = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient); if (exists_taxonomy_tag("ingredients", $ingredient_id)) { $ingredient_recognized = 1; @@ -1758,22 +1791,22 @@ sub parse_ingredients_text ($product_ref) { my @maybe_origins_ingredients = (); # California almonds - if (($product_lc eq "en") and ($ingredient =~ /^(\S+) (.+)$/)) { + if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+) (.+)$/)) { push @maybe_origins_ingredients, [$1, $2]; } # South Carolina black olives - if (($product_lc eq "en") and ($ingredient =~ /^(\S+ \S+) (.+)$/)) { + if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+ \S+) (.+)$/)) { push @maybe_origins_ingredients, [$1, $2]; } - if (($product_lc eq "en") and ($ingredient =~ /^(\S+ \S+ \S+) (.+)$/)) { + if (($ingredients_lc eq "en") and ($ingredient =~ /^(\S+ \S+ \S+) (.+)$/)) { push @maybe_origins_ingredients, [$1, $2]; } # Currently does not work: pitted California prunes # Oranges from Florida - if (defined $from{$product_lc}) { - my $from = $from{$product_lc}; + if (defined $from{$ingredients_lc}) { + my $from = $from{$ingredients_lc}; if ($ingredient =~ /^(.+)($from)(.+)$/i) { push @maybe_origins_ingredients, [$3, $1]; } @@ -1786,7 +1819,7 @@ sub parse_ingredients_text ($product_ref) { # skip origins that are too small (avoid false positives with country initials etc.) next if (length($maybe_origin) < 4); - my $origin_id = canonicalize_taxonomy_tag($product_lc, "origins", $maybe_origin); + my $origin_id = canonicalize_taxonomy_tag($ingredients_lc, "origins", $maybe_origin); if ((exists_taxonomy_tag("origins", $origin_id)) and ($origin_id ne "en:unknown")) { $debug_ingredients and $log->debug( @@ -1800,21 +1833,21 @@ sub parse_ingredients_text ($product_ref) { $origin = $origin_id; $ingredient = $maybe_ingredient; - $ingredient_id = canonicalize_taxonomy_tag($product_lc, "ingredients", $ingredient); + $ingredient_id = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient); last; } } # Try to remove ingredients processing "cooked rice" -> "rice" - if (defined $ingredients_processing_regexps{$product_lc}) { + if (defined $ingredients_processing_regexps{$ingredients_lc}) { my $matches = 0; my $new_ingredient = $ingredient; my $new_processing = ''; my $matching = 1; # remove prefixes / suffixes one by one while ($matching) { $matching = 0; - foreach - my $ingredient_processing_regexp_ref (@{$ingredients_processing_regexps{$product_lc}}) + foreach my $ingredient_processing_regexp_ref ( + @{$ingredients_processing_regexps{$ingredients_lc}}) { my $regexp = $ingredient_processing_regexp_ref->[1]; $debug_ingredients and $log->trace("checking processing regexps", @@ -1824,19 +1857,19 @@ sub parse_ingredients_text ($product_ref) { if ( # match before or after the ingredient, require a space ( - #($product_lc =~ /^(en|es|it|fr)$/) + #($ingredients_lc =~ /^(en|es|it|fr)$/) ( - ($product_lc eq 'bs') - or ($product_lc eq 'cs') - or ($product_lc eq 'en') - or ($product_lc eq 'es') - or ($product_lc eq 'fr') - or ($product_lc eq 'hr') - or ($product_lc eq 'it') - or ($product_lc eq 'mk') - or ($product_lc eq 'pl') - or ($product_lc eq 'sl') - or ($product_lc eq 'sr') + ($ingredients_lc eq 'bs') + or ($ingredients_lc eq 'cs') + or ($ingredients_lc eq 'en') + or ($ingredients_lc eq 'es') + or ($ingredients_lc eq 'fr') + or ($ingredients_lc eq 'hr') + or ($ingredients_lc eq 'it') + or ($ingredients_lc eq 'mk') + or ($ingredients_lc eq 'pl') + or ($ingredients_lc eq 'sl') + or ($ingredients_lc eq 'sr') ) and ($new_ingredient =~ /(^($regexp)\b|\b($regexp)$)/i) ) @@ -1844,17 +1877,17 @@ sub parse_ingredients_text ($product_ref) { # match before or after the ingredient, does not require a space or ( ( - ($product_lc eq 'de') - or ($product_lc eq 'hu') - or ($product_lc eq 'ja') - or ($product_lc eq 'nl') + ($ingredients_lc eq 'de') + or ($ingredients_lc eq 'hu') + or ($ingredients_lc eq 'ja') + or ($ingredients_lc eq 'nl') ) and ($new_ingredient =~ /(^($regexp)|($regexp)$)/i) ) # match after the ingredient, does not require a space # match before the ingredient, require a space - or ( ($product_lc eq 'fi') + or ( ($ingredients_lc eq 'fi') and ($new_ingredient =~ /(^($regexp)\b|($regexp)$)/i)) ) { @@ -1884,7 +1917,7 @@ sub parse_ingredients_text ($product_ref) { # Stop if we now have a known ingredient. # e.g. "jambon cru en tranches" -> keep "jambon cru". my $new_ingredient_id - = canonicalize_taxonomy_tag($product_lc, "ingredients", $new_ingredient); + = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $new_ingredient); if (exists_taxonomy_tag("ingredients", $new_ingredient_id)) { $debug_ingredients and $log->debug( @@ -1906,7 +1939,7 @@ sub parse_ingredients_text ($product_ref) { if ($matches) { my $new_ingredient_id - = canonicalize_taxonomy_tag($product_lc, "ingredients", $new_ingredient); + = canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $new_ingredient); if (exists_taxonomy_tag("ingredients", $new_ingredient_id)) { $debug_ingredients and $log->debug( "found existing ingredient after removing processing", @@ -1941,11 +1974,11 @@ sub parse_ingredients_text ($product_ref) { # We need to be careful with stopwords, "produit" was a stopword, # and "France" matched "produit de France" / made in France (bug #2927) - my $label_id = canonicalize_taxonomy_tag($product_lc, "labels", $ingredient); + my $label_id = canonicalize_taxonomy_tag($ingredients_lc, "labels", $ingredient); if (exists_taxonomy_tag("labels", $label_id)) { # Add the label to the product - add_tags_to_field($product_ref, $product_lc, "labels", $label_id); + add_tags_to_field($product_ref, $ingredients_lc, "labels", $label_id); $ingredient_recognized = 1; @@ -2139,8 +2172,8 @@ sub parse_ingredients_text ($product_ref) { ], ); - if (defined $ignore_regexps{$product_lc}) { - foreach my $regexp (@{$ignore_regexps{$product_lc}}) { + if (defined $ignore_regexps{$ingredients_lc}) { + foreach my $regexp (@{$ignore_regexps{$ingredients_lc}}) { if ($ingredient =~ /$regexp/i) { $debug_ingredients and $log->debug( @@ -2161,7 +2194,7 @@ sub parse_ingredients_text ($product_ref) { if (not $skip_ingredient) { my %ingredient = ( - id => get_taxonomyid($product_ref->{lc}, $ingredient_id), + id => get_taxonomyid($ingredients_lc, $ingredient_id), text => $ingredient ); @@ -2344,18 +2377,19 @@ sub compute_ingredients_tags ($product_ref) { my $field = "ingredients"; $product_ref->{ingredients_original_tags} = $product_ref->{ingredients_tags}; + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; if (defined $taxonomy_fields{$field}) { $product_ref->{$field . "_hierarchy"} = [ gen_ingredients_tags_hierarchy_taxonomy( - $product_ref->{lc}, join(", ", @{$product_ref->{ingredients_original_tags}}) + $ingredients_lc, join(", ", @{$product_ref->{ingredients_original_tags}}) ) ]; $product_ref->{$field . "_tags"} = []; my $unknown = 0; my $known = 0; foreach my $tag (@{$product_ref->{$field . "_hierarchy"}}) { - my $tagid = get_taxonomyid($product_ref->{lc}, $tag); + my $tagid = get_taxonomyid($ingredients_lc, $tag); push @{$product_ref->{$field . "_tags"}}, $tagid; if (exists_taxonomy_tag("ingredients", $tagid)) { $known++; @@ -2411,11 +2445,12 @@ sub extract_ingredients_from_text ($product_ref) { $product_ref->{specific_ingredients} = []; + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; + # Ingredients origins may be listed in the origin field # e.g. "Origin of the rice: Thailand." - my $product_lc = $product_ref->{lc}; - if (defined $product_ref->{"origin_" . $product_lc}) { - parse_origins_from_text($product_ref, $product_ref->{"origin_" . $product_lc}); + if (defined $product_ref->{"origin_" . $ingredients_lc}) { + parse_origins_from_text($product_ref, $product_ref->{"origin_" . $ingredients_lc}); } # Add specific ingredients from labels @@ -4253,7 +4288,6 @@ sub cut_ingredients_text_for_lang ($text, $language) { } sub clean_ingredients_text ($product_ref) { - if (defined $product_ref->{languages_codes}) { foreach my $language (keys %{$product_ref->{languages_codes}}) { @@ -4275,7 +4309,7 @@ sub clean_ingredients_text ($product_ref) { $product_ref->{"ingredients_text_" . $language} = $text; } - if ($language eq $product_ref->{lc}) { + if ($language eq ($product_ref->{ingredients_lc} || $product_ref->{lc})) { $product_ref->{"ingredients_text"} = $product_ref->{"ingredients_text_" . $language}; } } @@ -4299,9 +4333,9 @@ sub is_compound_word_with_dash ($word_lc, $compound_word) { # additive class + additive (e.g. "colour caramel" -> "colour : caramel" # warning: the additive class may also be the start of the name of an additive. # e.g. "regulatory kwasowości: kwas cytrynowy i cytryniany sodu." -> "kwas" means acid / acidifier. -sub separate_additive_class ($product_lc, $additive_class, $spaces, $colon, $after) { +sub separate_additive_class ($ingredients_lc, $additive_class, $spaces, $colon, $after) { - my $and = $and{$product_lc} || " and "; + my $and = $and{$ingredients_lc} || " and "; # check that we have an additive after the additive class # keep only what is before the first separator @@ -4322,13 +4356,13 @@ sub separate_additive_class ($product_lc, $additive_class, $spaces, $colon, $aft if ( ( not exists_taxonomy_tag( - "additives", canonicalize_taxonomy_tag($product_lc, "additives", $additive_class . " " . $after) + "additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $additive_class . " " . $after) ) ) and ( - exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($product_lc, "additives", $after)) + exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $after)) or ((defined $after2) - and exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($product_lc, "additives", $after2))) + and exists_taxonomy_tag("additives", canonicalize_taxonomy_tag($ingredients_lc, "additives", $after2))) ) ) { @@ -4372,7 +4406,7 @@ sub replace_additive ($number, $letter, $variant) { return $additive; } -=head2 develop_ingredients_categories_and_types ( $product_lc, $text ) - turn "oil (sunflower, olive and palm)" into "sunflower oil, olive oil, palm oil" +=head2 develop_ingredients_categories_and_types ( $ingredients_lc, $text ) - turn "oil (sunflower, olive and palm)" into "sunflower oil, olive oil, palm oil" Some ingredients are specified by an ingredient "category" (e.g. "oil", "flavouring") and a "type" (e.g. "sunflower", "palm" or "strawberry", "vanilla"). @@ -4555,11 +4589,11 @@ my %ingredients_categories_and_types = ( my @symbols = ('\*\*\*', '\*\*', '\*', '°°°', '°°', '°', '\(1\)', '\(2\)', '¹', '²'); my $symbols_regexp = join('|', @symbols); -sub develop_ingredients_categories_and_types ($product_lc, $text) { +sub develop_ingredients_categories_and_types ($ingredients_lc, $text) { - if (defined $ingredients_categories_and_types{$product_lc}) { + if (defined $ingredients_categories_and_types{$ingredients_lc}) { - foreach my $categories_and_types_ref (@{$ingredients_categories_and_types{$product_lc}}) { + foreach my $categories_and_types_ref (@{$ingredients_categories_and_types{$ingredients_lc}}) { my $category_regexp = ""; foreach my $category (@{$categories_and_types_ref->[0]}) { @@ -4572,10 +4606,10 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) { } $category_regexp =~ s/^\|//; - if ($product_lc eq "en") { + if ($ingredients_lc eq "en") { $category_regexp = '(?:organic |fair trade )*(?:' . $category_regexp . ')(?:' . $symbols_regexp . ')*'; } - elsif ($product_lc eq "fr") { + elsif ($ingredients_lc eq "fr") { $category_regexp = '(?:' . $category_regexp . ')(?: bio| biologique| équitable|s|\s|' . $symbols_regexp . ')*'; } @@ -4599,36 +4633,36 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) { $text =~ s/($type_regexp)-($type_regexp)/$1, $2/g; my $and = ' - '; - if (defined $and{$product_lc}) { - $and = $and{$product_lc}; + if (defined $and{$ingredients_lc}) { + $and = $and{$ingredients_lc}; } my $of = ' - '; - if (defined $of{$product_lc}) { - $of = $of{$product_lc}; + if (defined $of{$ingredients_lc}) { + $of = $of{$ingredients_lc}; } my $and_of = ' - '; - if (defined $and_of{$product_lc}) { - $and_of = $and_of{$product_lc}; + if (defined $and_of{$ingredients_lc}) { + $and_of = $and_of{$ingredients_lc}; } my $and_or = ' - '; - if (defined $and_or{$product_lc}) { - $and_or = $and_or{$product_lc}; + if (defined $and_or{$ingredients_lc}) { + $and_or = $and_or{$ingredients_lc}; } - if (($product_lc eq "en") or ($product_lc eq "ru") or ($product_lc eq "pl")) { + if (($ingredients_lc eq "en") or ($ingredients_lc eq "ru") or ($ingredients_lc eq "pl")) { # vegetable oil (palm, sunflower and olive) $text - =~ s/($category_regexp)(?::|\(|\[| | $of )+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, |$and|$of|$and_of|$and_or)+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)(?::|\(|\[| | $of )+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, |$and|$of|$and_of|$and_or)+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($ingredients_lc,$1,$2)/ieg; # vegetable oil (palm) $text - =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($ingredients_lc,$1,$2)/ieg; # vegetable oil: palm $text - =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($ingredients_lc,$1,$2)/ieg; } - elsif ($product_lc eq "fr") { + elsif ($ingredients_lc eq "fr") { # arôme naturel de pomme avec d'autres âromes $text =~ s/ (ou|et|avec) (d')?autres /, /g; @@ -4640,21 +4674,21 @@ sub develop_ingredients_categories_and_types ($product_lc, $text) { # TODO 18/07/2020 remove when we have a better solution $text =~ s/fer (é|e)l(é|e)mentaire/fer_élémentaire/ig; $text - =~ s/($category_regexp)(?::|\(|\[| | de | d')+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, | et | de | et de | et d'| d')+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)(?::|\(|\[| | de | d')+((($type_regexp)($symbols_regexp|\s)*( |\/| \/ | - |,|, | et | de | et de | et d'| d')+)+($type_regexp)($symbols_regexp|\s)*)\b(\s?(\)|\]))?/normalize_enumeration($ingredients_lc,$1,$2)/ieg; $text =~ s/fer_élémentaire/fer élémentaire/ig; # huile végétale (colza) $text - =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)\s?(?:\(|\[)\s?($type_regexp)\b(\s?(\)|\]))/normalize_enumeration($ingredients_lc,$1,$2)/ieg; # huile végétale : colza, $text - =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($product_lc,$1,$2)/ieg; + =~ s/($category_regexp)\s?(?::)\s?($type_regexp)(?=$separators|$)/normalize_enumeration($ingredients_lc,$1,$2)/ieg; } } # Some additives have "et" in their name: need to recombine them - if ($product_lc eq "fr") { + if ($ingredients_lc eq "fr") { # Sels de sodium et de potassium de complexes cupriques de chlorophyllines, @@ -4702,7 +4736,7 @@ INFO return $text; } -=head2 preparse_ingredients_text ($product_lc, $text) - normalize the ingredient list to make parsing easier +=head2 preparse_ingredients_text ($ingredients_lc, $text) - normalize the ingredient list to make parsing easier This function transform the ingredients list in a more normalized list that is easier to parse. @@ -4729,7 +4763,7 @@ It does the following: =cut -sub preparse_ingredients_text ($product_lc, $text) { +sub preparse_ingredients_text ($ingredients_lc, $text) { not defined $text and return; @@ -4741,11 +4775,11 @@ sub preparse_ingredients_text ($product_lc, $text) { state $prev_text = ''; state $prev_return = ''; - if (($product_lc eq $prev_lc) && ($text eq $prev_text)) { + if (($ingredients_lc eq $prev_lc) && ($text eq $prev_text)) { return $prev_return; } - $prev_lc = $product_lc; + $prev_lc = $ingredients_lc; $prev_text = $text; if ((scalar keys %labels_regexps) == 0) { @@ -4756,19 +4790,19 @@ sub preparse_ingredients_text ($product_lc, $text) { init_origins_regexps(); } - my $and = $and{$product_lc} || " and "; + my $and = $and{$ingredients_lc} || " and "; my $and_without_spaces = $and; $and_without_spaces =~ s/^ //; $and_without_spaces =~ s/ $//; my $of = ' - '; - if (defined $of{$product_lc}) { - $of = $of{$product_lc}; + if (defined $of{$ingredients_lc}) { + $of = $of{$ingredients_lc}; } my $and_of = ' - '; - if (defined $and_of{$product_lc}) { - $and_of = $and_of{$product_lc}; + if (defined $and_of{$ingredients_lc}) { + $and_of = $and_of{$ingredients_lc}; } # Spanish "and" is y or e when before "i" or "hi" @@ -4779,8 +4813,8 @@ sub preparse_ingredients_text ($product_lc, $text) { # replace "and / or" by "and" # except if followed by a separator, a digit, or "and", to avoid false positives my $and_or = ' - '; - if (defined $and_or{$product_lc}) { - $and_or = $and_or{$product_lc}; + if (defined $and_or{$ingredients_lc}) { + $and_or = $and_or{$ingredients_lc}; $text =~ s/($and_or)(?!($and_without_spaces |\d|$separators))/$and/ig; } @@ -4802,7 +4836,7 @@ sub preparse_ingredients_text ($product_lc, $text) { # number + gr / grams -> g $text =~ s/(\d\s*)(gr|gram|grams)\b/$1g/ig; - if ($product_lc eq 'fr') { + if ($ingredients_lc eq 'fr') { $text =~ s/(\d\s*)(gramme|grammes)\b/$1g/ig; } @@ -4815,7 +4849,7 @@ sub preparse_ingredients_text ($product_lc, $text) { $text =~ s/—/-/g; # abbreviations, replace language specific abbreviations first - foreach my $abbreviations_lc ($product_lc, "all") { + foreach my $abbreviations_lc ($ingredients_lc, "all") { if (defined $abbreviations{$abbreviations_lc}) { foreach my $abbreviation_ref (@{$abbreviations{$abbreviations_lc}}) { my $source = $abbreviation_ref->[0]; @@ -4835,7 +4869,7 @@ sub preparse_ingredients_text ($product_lc, $text) { # céleri - rave 3.9% -> stop at numbers $text - =~ s/((^|$separators)([^,;\-\/\.0-9]+?) - ([^,;\-\/\.0-9]+?)(?=[0-9]|$separators|$))/is_compound_word_with_dash($product_lc,$1)/ieg; + =~ s/((^|$separators)([^,;\-\/\.0-9]+?) - ([^,;\-\/\.0-9]+?)(?=[0-9]|$separators|$))/is_compound_word_with_dash($ingredients_lc,$1)/ieg; # vitamins... # vitamines A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E (lactose, protéines de lait) @@ -4863,7 +4897,7 @@ sub preparse_ingredients_text ($product_lc, $text) { = '(\d{3}|\d{4})(( |-|\.)?([abcdefgh]))?(( |-|\.)?((' . $roman_numerals . ')|\((' . $roman_numerals . ')\)))?'; $text - =~ s/\b(e|ins|sin|i-n-s|s-i-n|i\.n\.s\.?|s\.i\.n\.?)(:|\(|\[| | n| nb|#|°)+((($additivesregexp)( |\/| \/ | - |,|, |$and))+($additivesregexp))\b(\s?(\)|\]))?/normalize_additives_enumeration($product_lc,$3)/ieg; + =~ s/\b(e|ins|sin|i-n-s|s-i-n|i\.n\.s\.?|s\.i\.n\.?)(:|\(|\[| | n| nb|#|°)+((($additivesregexp)( |\/| \/ | - |,|, |$and))+($additivesregexp))\b(\s?(\)|\]))?/normalize_additives_enumeration($ingredients_lc,$3)/ieg; # in India: INS 240 instead of E 240, bug #1133) # also INS N°420, bug #3618 @@ -4896,11 +4930,11 @@ sub preparse_ingredients_text ($product_lc, $text) { # additive class + additive (e.g. "colour caramel" -> "colour : caramel" # warning: the additive class may also be the start of the name of an additive. # e.g. "regulatory kwasowości: kwas cytrynowy i cytryniany sodu." -> "kwas" means acid / acidifier. - if (defined $additives_classes_regexps{$product_lc}) { - my $regexp = $additives_classes_regexps{$product_lc}; + if (defined $additives_classes_regexps{$ingredients_lc}) { + my $regexp = $additives_classes_regexps{$ingredients_lc}; # negative look ahead so that the additive class is not preceded by other words # e.g. "de l'acide" should not match "acide" - $text =~ s/(?debug("preparse_ingredients_text - before language specific preparsing", {text => $text}) if $log->is_debug(); - if ($product_lc eq 'de') { + if ($ingredients_lc eq 'de') { # deletes comma in "Bienenwachs, weiß und gelb" since it is just one ingredient $text =~ s/Bienenwachs, weiß und gelb/Bienenwachs weiß und gelb/ig; # deletes brackets in "Bienenwachs, weiß und gelb" since it is just one ingredient $text =~ s/Bienenwachs \(weiß und gelb\)/Bienenwachs weiß und gelb/ig; } - elsif ($product_lc eq 'es') { + elsif ($ingredients_lc eq 'es') { # Special handling for sal as it can mean salt or shorea robusta # aceites vegetales (palma, shea, sal (shorea robusta), hueso de mango) $text =~ s/\bsal \(shorea robusta\)/shorea robusta/ig; $text =~ s/\bshorea robusta \(sal\)/shorea robusta/ig; } - elsif ($product_lc eq 'fi') { + elsif ($ingredients_lc eq 'fi') { # Organic label can appear as a part of a longer word. # Separate it so it can be detected $text =~ s/\b(luomu)\B/$1 /ig; } - elsif ($product_lc eq 'fr') { + elsif ($ingredients_lc eq 'fr') { # huiles de palme et de @@ -4974,14 +5008,14 @@ sub preparse_ingredients_text ($product_lc, $text) { $text =~ s/dient\(s\)/dients/ig; $text =~ s/\bissu(\(e\))?(\(s\))?/issu/ig; } - elsif ($product_lc eq 'pl') { + elsif ($ingredients_lc eq 'pl') { # remove stopwords $text =~ s/w? (zmiennych|różnych)? proporcjach?//i; } - $text = develop_ingredients_categories_and_types($product_lc, $text); + $text = develop_ingredients_categories_and_types($ingredients_lc, $text); # vitamines A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E # vitamines (A, B1, B2, B5, B6, B9, B12, C, D, H, PP et E) @@ -5004,22 +5038,22 @@ sub preparse_ingredients_text ($product_lc, $text) { # Add synonyms in target language if (defined $translations_to{vitamins}) { foreach my $vitamin (keys %{$translations_to{vitamins}}) { - if (defined $translations_to{vitamins}{$vitamin}{$product_lc}) { - push @vitaminssuffixes, $translations_to{vitamins}{$vitamin}{$product_lc}; + if (defined $translations_to{vitamins}{$vitamin}{$ingredients_lc}) { + push @vitaminssuffixes, $translations_to{vitamins}{$vitamin}{$ingredients_lc}; } } } # Add synonyms in target language my $vitamin_in_lc - = get_string_id_for_lang($product_lc, display_taxonomy_tag($product_lc, "ingredients", "en:vitamins")); + = get_string_id_for_lang($ingredients_lc, display_taxonomy_tag($ingredients_lc, "ingredients", "en:vitamins")); $vitamin_in_lc =~ s/^\w\w://; if ( (defined $synonyms_for{ingredients}) - and (defined $synonyms_for{ingredients}{$product_lc}) - and (defined $synonyms_for{ingredients}{$product_lc}{$vitamin_in_lc})) + and (defined $synonyms_for{ingredients}{$ingredients_lc}) + and (defined $synonyms_for{ingredients}{$ingredients_lc}{$vitamin_in_lc})) { - foreach my $synonym (@{$synonyms_for{ingredients}{$product_lc}{$vitamin_in_lc}}) { + foreach my $synonym (@{$synonyms_for{ingredients}{$ingredients_lc}{$vitamin_in_lc}}) { $vitaminsprefixregexp .= '|' . $synonym; } } @@ -5053,7 +5087,7 @@ sub preparse_ingredients_text ($product_lc, $text) { # vitamines (B1, acide folique (B9)) <-- we need to match (B9) which is not followed by a \b boundary, hence the ((\s?((\)|\]))|\b)) in the regexp below $text - =~ s/($vitaminsprefixregexp)(:|\(|\[| )+((($vitaminssuffixregexp)( |\/| \/ | - |,|, |$and)+)+($vitaminssuffixregexp))((\s?((\)|\]))|\b))/normalize_vitamins_enumeration($product_lc,$3)/ieg; + =~ s/($vitaminsprefixregexp)(:|\(|\[| )+((($vitaminssuffixregexp)( |\/| \/ | - |,|, |$and)+)+($vitaminssuffixregexp))((\s?((\)|\]))|\b))/normalize_vitamins_enumeration($ingredients_lc,$3)/ieg; # Allergens and traces # Traces de lait, d'oeufs et de soja. @@ -5061,36 +5095,36 @@ sub preparse_ingredients_text ($product_lc, $text) { foreach my $allergens_type ("allergens", "traces") { - if (defined $contains_or_may_contain_regexps{$allergens_type}{$product_lc}) { + if (defined $contains_or_may_contain_regexps{$allergens_type}{$ingredients_lc}) { - my $contains_or_may_contain_regexp = $contains_or_may_contain_regexps{$allergens_type}{$product_lc}; - my $allergens_regexp = $allergens_regexps{$product_lc}; + my $contains_or_may_contain_regexp = $contains_or_may_contain_regexps{$allergens_type}{$ingredients_lc}; + my $allergens_regexp = $allergens_regexps{$ingredients_lc}; # stopwords # e.g. Kann Spuren von Senf und Sellerie enthalten. my $stopwords = ""; - if (defined $allergens_stopwords{$product_lc}) { - $stopwords = $allergens_stopwords{$product_lc}; + if (defined $allergens_stopwords{$ingredients_lc}) { + $stopwords = $allergens_stopwords{$ingredients_lc}; } # $contains_or_may_contain_regexp may be the end of a sentence, remove the beginning # e.g. this product has been manufactured in a factory that also uses... # Some text with comma May contain ... -> Some text with comma, May contain # ! does not work in German and languages that have words with a capital letter - if ($product_lc ne "de") { + if ($ingredients_lc ne "de") { my $ucfirst_contains_or_may_contain_regexp = $contains_or_may_contain_regexp; $ucfirst_contains_or_may_contain_regexp =~ s/(^|\|)(\w)/$1 . uc($2)/ieg; $text =~ s/([a-z]) ($ucfirst_contains_or_may_contain_regexp)/$1, $2/g; } #$log->debug("allergens regexp", { regex => "s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b(:|\(|\[| |$and|$of)+((($allergens_regexp)( |\/| \/ | - |,|, |$and|$of|$and_of)+)+($allergens_regexp))\b(s?(\)|\]))?" }) if $log->is_debug(); - #$log->debug("allergens", { lc => $product_lc, may_contain_regexps => \%may_contain_regexps, contains_or_may_contain_regexp => $contains_or_may_contain_regexp, text => $text }) if $log->is_debug(); + #$log->debug("allergens", { lc => $ingredients_lc, may_contain_regexps => \%may_contain_regexps, contains_or_may_contain_regexp => $contains_or_may_contain_regexp, text => $text }) if $log->is_debug(); # warning: we should remove a parenthesis at the end only if we remove one at the beginning # e.g. contains (milk, eggs) -> contains milk, eggs # chocolate (contains milk) -> chocolate (contains milk) $text - =~ s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b((:|\(|\[| |$of)+)((_?($allergens_regexp)_?\b((\s)($stopwords)\b)*( |\/| \/ | - |,|, |$and|$of|$and_of)+)*_?($allergens_regexp)_?)\b((\s)($stopwords)\b)*(\s?(\)|\]))?/normalize_allergens_enumeration($allergens_type,$product_lc,$3,$5,$17)/ieg; + =~ s/([^,-\.;\(\)\/]*)\b($contains_or_may_contain_regexp)\b((:|\(|\[| |$of)+)((_?($allergens_regexp)_?\b((\s)($stopwords)\b)*( |\/| \/ | - |,|, |$and|$of|$and_of)+)*_?($allergens_regexp)_?)\b((\s)($stopwords)\b)*(\s?(\)|\]))?/normalize_allergens_enumeration($allergens_type,$ingredients_lc,$3,$5,$17)/ieg; # we may have added an extra dot in order to make sure we have at least one $text =~ s/\.\./\./g; } @@ -5101,7 +5135,7 @@ sub preparse_ingredients_text ($product_lc, $text) { # Pâte de cacao°* du Pérou 65 %, sucre de canne°*, beurre de cacao°*. °Issus de l'agriculture biologique (100 %). *Issus du commerce équitable (100 % du poids total avec 93 % SPP). # riz* de Camargue IGP(1) (16,5%) (riz complet*, riz rouge complet*, huiles* (tournesol*, olive* vierge extra), sel marin. *issus de l'agriculture biologique. (1) IGP : Indication Géographique Protégée. - if (defined $labels_regexps{$product_lc}) { + if (defined $labels_regexps{$ingredients_lc}) { foreach my $symbol (@symbols) { # Find the last occurence of the symbol or symbol in parenthesis: * (*) @@ -5110,7 +5144,7 @@ sub preparse_ingredients_text ($product_lc, $text) { my $after = $'; #print STDERR "symbol: $symbol - after: $after\n"; foreach my $labelid (@labels) { - my $regexp = $labels_regexps{$product_lc}{$labelid}; + my $regexp = $labels_regexps{$ingredients_lc}{$labelid}; if (defined $regexp) { #print STDERR "-- label: $labelid - regexp: $regexp\n"; # try to also match optional precisions like "Issus de l'agriculture biologique (100 % du poids total)" @@ -5119,8 +5153,8 @@ sub preparse_ingredients_text ($product_lc, $text) { my $label = $1; $text =~ s/^(.*)(\($symbol\)|$symbol)(?!\))\s?(:|=)?\s?$label\s*(\([^\)]+\))?\s*\.?\s*/$1 /i; - my $product_lc_label = display_taxonomy_tag($product_lc, "labels", $labelid); - $text =~ s/$symbol/ $product_lc_label /g; + my $ingredients_lc_label = display_taxonomy_tag($ingredients_lc, "labels", $labelid); + $text =~ s/$symbol/ $ingredients_lc_label /g; last; } } @@ -5144,10 +5178,10 @@ sub preparse_ingredients_text ($product_lc, $text) { sub extract_ingredients_classes_from_text ($product_ref) { not defined $product_ref->{ingredients_text} and return; - - my $text = preparse_ingredients_text($product_ref->{lc}, $product_ref->{ingredients_text}); + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; + my $text = preparse_ingredients_text($ingredients_lc, $product_ref->{ingredients_text}); # do not match anything if we don't have a translation for "and" - my $and = $and{$product_ref->{lc}} || " will not match "; + my $and = $and{$ingredients_lc} || " will not match "; $and =~ s/ /-/g; # remove % / percent (to avoid identifying 100% as E100 in some cases) @@ -5157,7 +5191,7 @@ sub extract_ingredients_classes_from_text ($product_ref) { my @ingredients_ids = (); foreach my $ingredient (@ingredients) { - my $ingredientid = get_string_id_for_lang($product_ref->{lc}, $ingredient); + my $ingredientid = get_string_id_for_lang($ingredients_lc, $ingredient); if ((defined $ingredientid) and ($ingredientid ne '')) { # split additives @@ -5170,16 +5204,15 @@ sub extract_ingredients_classes_from_text ($product_ref) { #print STDERR "ingredients_classes - ingredient1: $ingredientid1 - ingredient2: $ingredientid2\n"; # check if the whole ingredient is an additive - my $canon_ingredient_additive - = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid); + my $canon_ingredient_additive = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid); if (not exists_taxonomy_tag("additives", $canon_ingredient_additive)) { # otherwise check the 2 sub ingredients my $canon_ingredient_additive1 - = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid1); + = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid1); my $canon_ingredient_additive2 - = canonicalize_taxonomy_tag($product_ref->{lc}, "additives", $ingredientid2); + = canonicalize_taxonomy_tag($ingredients_lc, "additives", $ingredientid2); if ( (exists_taxonomy_tag("additives", $canon_ingredient_additive1)) and (exists_taxonomy_tag("additives", $canon_ingredient_additive2))) @@ -5253,7 +5286,7 @@ sub extract_ingredients_classes_from_text ($product_ref) { # additive class? my $canon_ingredient_additive_class - = canonicalize_taxonomy_tag($product_ref->{lc}, "additives_classes", $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "additives_classes", $ingredient_id_copy); if (exists_taxonomy_tag("additives_classes", $canon_ingredient_additive_class)) { $current_additive_class = $canon_ingredient_additive_class; @@ -5262,21 +5295,20 @@ sub extract_ingredients_classes_from_text ($product_ref) { } # additive? - my $canon_ingredient = canonicalize_taxonomy_tag($product_ref->{lc}, $tagtype, $ingredient_id_copy); + my $canon_ingredient = canonicalize_taxonomy_tag($ingredients_lc, $tagtype, $ingredient_id_copy); # in Hong Kong, the E- can be omitted in E-numbers my $canon_e_ingredient - = canonicalize_taxonomy_tag($product_ref->{lc}, $tagtype, "e" . $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, $tagtype, "e" . $ingredient_id_copy); my $canon_ingredient_vitamins - = canonicalize_taxonomy_tag($product_ref->{lc}, "vitamins", $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "vitamins", $ingredient_id_copy); my $canon_ingredient_minerals - = canonicalize_taxonomy_tag($product_ref->{lc}, "minerals", $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "minerals", $ingredient_id_copy); my $canon_ingredient_amino_acids - = canonicalize_taxonomy_tag($product_ref->{lc}, "amino_acids", $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "amino_acids", $ingredient_id_copy); my $canon_ingredient_nucleotides - = canonicalize_taxonomy_tag($product_ref->{lc}, "nucleotides", $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "nucleotides", $ingredient_id_copy); my $canon_ingredient_other_nutritional_substances - = canonicalize_taxonomy_tag($product_ref->{lc}, "other_nutritional_substances", - $ingredient_id_copy); + = canonicalize_taxonomy_tag($ingredients_lc, "other_nutritional_substances", $ingredient_id_copy); $product_ref->{$tagtype} .= " [ $ingredient_id_copy -> $canon_ingredient "; @@ -5496,14 +5528,14 @@ sub extract_ingredients_classes_from_text ($product_ref) { and ( not exists_taxonomy_tag( "ingredients", - canonicalize_taxonomy_tag($product_ref->{lc}, "ingredients", $ingredient_id_copy) + canonicalize_taxonomy_tag($ingredients_lc, "ingredients", $ingredient_id_copy) ) ) ) { my ($corrected_canon_tagid, $corrected_tagid, $corrected_tag) - = spellcheck_taxonomy_tag($product_ref->{lc}, $tagtype, $ingredient_id_copy); + = spellcheck_taxonomy_tag($ingredients_lc, $tagtype, $ingredient_id_copy); if ( (defined $corrected_canon_tagid) and ($corrected_tag ne $ingredient_id_copy) @@ -5525,10 +5557,10 @@ sub extract_ingredients_classes_from_text ($product_ref) { $product_ref->{$tagtype} .= " -- spell correction (lc: " - . $product_ref->{lc} + . $ingredients_lc . "): $ingredient_id_copy -> $corrected_tag"; print STDERR "spell correction (lc: " - . $product_ref->{lc} + . $ingredients_lc . "): $ingredient_id_copy -> $corrected_tag - code: $product_ref->{code}\n"; $ingredient_id_copy = $corrected_tag; @@ -5543,11 +5575,11 @@ sub extract_ingredients_classes_from_text ($product_ref) { # try to shorten the ingredient to make it less specific, to see if it matches then # in last resort, try with the first (in French, Spanish) or last (in English) word only - if (($product_ref->{lc} eq 'en') and ($ingredient_id_copy =~ /^([^-]+)-/)) { + if (($ingredients_lc eq 'en') and ($ingredient_id_copy =~ /^([^-]+)-/)) { # soy-lecithin -> lecithin $ingredient_id_copy = $'; } - elsif ( (($product_ref->{lc} eq 'es') or ($product_ref->{lc} eq 'fr')) + elsif ( (($ingredients_lc eq 'es') or ($ingredients_lc eq 'fr')) and ($ingredient_id_copy =~ /-([^-]+)$/)) { # lecitina-de-girasol -> lecitina-de -> lecitina @@ -5707,7 +5739,7 @@ sub extract_ingredients_classes_from_text ($product_ref) { # keep the old additives for France until we can fix the new taxonomy matching to support all special cases # e.g. lecithine de soja - #if ($product_ref->{lc} ne 'fr') { + #if ($ingredients_lc ne 'fr') { # $product_ref->{additives_tags} = $product_ref->{new_additives_tags}; # $product_ref->{additives_tags_n} = $product_ref->{new_additives_tags_n}; #} @@ -5796,6 +5828,7 @@ sub extract_ingredients_classes_from_text ($product_ref) { sub replace_allergen ($language, $product_ref, $allergen, $before) { + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; my $field = "allergens"; my $traces_regexp = $may_contain_regexps{$language}; @@ -5805,7 +5838,7 @@ sub replace_allergen ($language, $product_ref, $allergen, $before) { } # to build the product allergens list, just use the ingredients in the main language - if ($language eq $product_ref->{lc}) { + if ($language eq $ingredients_lc) { # skip allergens like "moutarde et céleri" (will be caught later by replace_allergen_between_separators) if (not(($language eq 'fr') and $allergen =~ / et /i)) { $product_ref->{$field . "_from_ingredients"} .= $allergen . ', '; @@ -5817,6 +5850,7 @@ sub replace_allergen ($language, $product_ref, $allergen, $before) { sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) { + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; my $field = "allergens"; my $traces_regexp = $may_contain_regexps{$language}; @@ -5830,7 +5864,7 @@ sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) { if (exists_taxonomy_tag("allergens", $tagid)) { #$allergen = display_taxonomy_tag($product_ref->{lang},"allergens", $tagid); # to build the product allergens list, just use the ingredients in the main language - if ($language eq $product_ref->{lc}) { + if ($language eq $ingredients_lc) { $product_ref->{$field . "_from_ingredients"} .= $allergen . ', '; } return '' . $allergen . ''; @@ -5842,6 +5876,7 @@ sub replace_allergen_in_caps ($language, $product_ref, $allergen, $before) { sub replace_allergen_between_separators ($language, $product_ref, $start_separator, $allergen, $end_separator, $before) { + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; my $field = "allergens"; #print STDERR "replace_allergen_between_separators - allergen: $allergen\n"; @@ -5895,7 +5930,7 @@ sub replace_allergen_between_separators ($language, $product_ref, $start_separat if (($tagid ne "en:none") and (exists_taxonomy_tag("allergens", $tagid))) { #$allergen = display_taxonomy_tag($product_ref->{lang},"allergens", $tagid); # to build the product allergens list, just use the ingredients in the main language - if ($language eq $product_ref->{lc}) { + if ($language eq $ingredients_lc) { $product_ref->{$field . "_from_ingredients"} .= $allergen . ', '; } return @@ -5993,6 +6028,8 @@ sub detect_allergens_from_text ($product_ref) { init_allergens_regexps(); } + my $ingredients_lc = $product_ref->{ingredients_lc} || $product_ref->{lc}; + # Keep allergens entered by users in the allergens and traces field foreach my $field ("allergens", "traces") { @@ -6072,7 +6109,7 @@ sub detect_allergens_from_text ($product_ref) { $product_ref->{"ingredients_text_with_allergens_" . $language} = $text; - if ($language eq $product_ref->{lc}) { + if ($language eq $ingredients_lc) { $product_ref->{"ingredients_text_with_allergens"} = $text; } @@ -6083,8 +6120,8 @@ sub detect_allergens_from_text ($product_ref) { # Use the language the tag have been entered in my $traces_regexp; - if (defined $may_contain_regexps{$product_ref->{traces_lc} || $product_ref->{lc}}) { - $traces_regexp = $may_contain_regexps{$product_ref->{traces_lc} || $product_ref->{lc}}; + if (defined $may_contain_regexps{$product_ref->{traces_lc} || $ingredients_lc}) { + $traces_regexp = $may_contain_regexps{$product_ref->{traces_lc} || $ingredients_lc}; } if ( (defined $traces_regexp) @@ -6106,7 +6143,7 @@ sub detect_allergens_from_text ($product_ref) { # regenerate allergens and traces from the allergens_tags field so that it is prefixed with the values in the # main language of the product (which may be different than the $tag_lc language of the interface) - my $tag_lc = $product_ref->{$field . "_lc"} || $product_ref->{lc} || "?"; + my $tag_lc = $product_ref->{$field . "_lc"} || $ingredients_lc || "?"; $product_ref->{$field . "_from_user"} = "($tag_lc) " . ($product_ref->{$field} // ""); $product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($tag_lc, $field, $product_ref->{$field})]; $product_ref->{$field} = join(',', @{$product_ref->{$field . "_hierarchy"}}); @@ -6122,11 +6159,11 @@ sub detect_allergens_from_text ($product_ref) { $allergens .= ", " . $product_ref->{$field}; } - $product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($product_ref->{lc}, $field, $allergens)]; + $product_ref->{$field . "_hierarchy"} = [gen_tags_hierarchy_taxonomy($ingredients_lc, $field, $allergens)]; $product_ref->{$field . "_tags"} = []; # print STDERR "result for $field : "; foreach my $tag (@{$product_ref->{$field . "_hierarchy"}}) { - push @{$product_ref->{$field . "_tags"}}, get_taxonomyid($product_ref->{lc}, $tag); + push @{$product_ref->{$field . "_tags"}}, get_taxonomyid($ingredients_lc, $tag); # print STDERR " - $tag"; } # print STDERR "\n"; diff --git a/lib/ProductOpener/KnowledgePanels.pm b/lib/ProductOpener/KnowledgePanels.pm index af37041f42271..5c9dadc450ead 100644 --- a/lib/ProductOpener/KnowledgePanels.pm +++ b/lib/ProductOpener/KnowledgePanels.pm @@ -1146,7 +1146,7 @@ sub create_ingredients_panel ($product_ref, $target_lc, $target_cc, $options_ref my $ingredients_text = $product_ref->{ingredients_text}; my $ingredients_text_with_allergens = $product_ref->{ingredients_text_with_allergens}; - my $ingredients_text_lc = $product_ref->{lc}; + my $ingredients_text_lc = $product_ref->{ingredients_lc}; if ( (defined $product_ref->{"ingredients_text" . "_" . $target_lc}) and ($product_ref->{"ingredients_text" . "_" . $target_lc} ne '')) diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm index 55489bbec5238..ce0c4c01db151 100644 --- a/lib/ProductOpener/Products.pm +++ b/lib/ProductOpener/Products.pm @@ -3555,6 +3555,8 @@ sub analyze_and_enrich_product_data ($product_ref, $response_ref) { compute_languages($product_ref); # need languages for allergens detection and cleaning ingredients # Ingredients classes + # Select best language to parse ingredients + $product_ref->{ingredients_lc} = select_ingredients_lc($product_ref); clean_ingredients_text($product_ref); extract_ingredients_from_text($product_ref); extract_ingredients_classes_from_text($product_ref); diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json b/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json index 96e5569c9e77f..98cd32470334c 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-existing-product.json @@ -646,6 +646,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json index 675c65e2566bc..f1bd9847d492b 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all-knowledge-panels.json @@ -646,6 +646,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -1383,7 +1384,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json index 96e5569c9e77f..98cd32470334c 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-all.json @@ -646,6 +646,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json index ca534baefae86..a4301e0fe5548 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-attribute-groups-all-knowledge-panels.json @@ -970,6 +970,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -1707,7 +1708,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json b/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json index 03596cf193f6e..d53ccae9528b6 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-fields-raw.json @@ -641,6 +641,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json index 863870adc89db..715a98a700c12 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels-fr.json @@ -699,7 +699,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json index 8644d569d41d5..43dce689ec063 100644 --- a/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v2_product_read/get-knowledge-panels.json @@ -699,7 +699,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json b/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json index d97ec673030e5..026ef85c2d577 100644 --- a/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json +++ b/tests/integration/expected_test_results/api_v2_product_write/get-product-auth-good-password.json @@ -582,6 +582,7 @@ "en:added-sugar", "en:disaccharide" ], + "ingredients_lc" : "fr", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v2_product_write/get-product.json b/tests/integration/expected_test_results/api_v2_product_write/get-product.json index c26cfc2fc397f..32f628c6d0762 100644 --- a/tests/integration/expected_test_results/api_v2_product_write/get-product.json +++ b/tests/integration/expected_test_results/api_v2_product_write/get-product.json @@ -582,6 +582,7 @@ "en:added-sugar", "en:disaccharide" ], + "ingredients_lc" : "fr", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json index c04f3777ac380..32982ffc98df1 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-existing-product.json @@ -647,6 +647,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json index 3f7e555d96acf..c873b6cabf3e2 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all-knowledge-panels.json @@ -647,6 +647,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -1384,7 +1385,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json index c84d3a1cc9263..ef87ab692450a 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-all.json @@ -647,6 +647,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json index 6a5ffd3ba9eaa..9bf539927a8f7 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-attribute-groups-all-knowledge-panels.json @@ -971,6 +971,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -1708,7 +1709,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json b/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json index 72ba6ffd403a7..eb556cdb92b09 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-fields-raw.json @@ -642,6 +642,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json index 9ebad360bb7d1..e78bfe6f21f92 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels-fr.json @@ -700,7 +700,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json index b5dd4202232ff..029fdc4c3b73b 100644 --- a/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json +++ b/tests/integration/expected_test_results/api_v3_product_read/get-knowledge-panels.json @@ -700,7 +700,7 @@ { "element_type" : "text", "text_element" : { - "html" : "apple, milk, eggs, palm oil" + "html" : "en: apple, milk, eggs, palm oil" } }, { diff --git a/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json b/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json index ec690f3d9b90e..f2d5e229b59f5 100644 --- a/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json +++ b/tests/integration/expected_test_results/api_v3_product_write/patch-request-fields-all.json @@ -330,6 +330,7 @@ "informers_tags" : [ "openfoodfacts-contributors" ], + "ingredients_lc" : "en", "interface_version_created" : "20221102/api/v3", "lang" : "en", "languages" : {}, diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json index 25372c4c1d22a..d9f9ac1efd007 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390017165.json @@ -363,6 +363,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json index 3686f9eacddec..5ce66ffe734f6 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020745.json @@ -360,6 +360,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json index 36250de64be25..7bd9c972b7f03 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020806.json @@ -349,6 +349,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json index 45d4f01c8eb61..9df47e52ee419 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390020998.json @@ -363,6 +363,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json index b22843a441743..26475ac92c658 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021001.json @@ -357,6 +357,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json index d62d97ff9828a..c0c8d326cf357 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021469.json @@ -354,6 +354,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json index e4e7aa16f6d53..e2b8321af5981 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021544.json @@ -357,6 +357,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json index 069ca885587d6..f15a093072518 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021568.json @@ -355,6 +355,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json index 48cec094f2192..a2afedd48ce99 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390021926.json @@ -347,6 +347,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json index c6986f837ae25..dd76b92e032ce 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024781.json @@ -382,6 +382,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json index 6ab0628a9ac6d..6a8765c24cc9b 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024804.json @@ -371,6 +371,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json index 6524ba5ebbfc9..60c66fe7a5226 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024842.json @@ -372,6 +372,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json index 5ce5a0ef7b0f6..d1c652125bc7c 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390024866.json @@ -372,6 +372,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json index 9867684c57bd5..a9b27cd186ad3 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025399.json @@ -364,6 +364,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json index 651b7855cf80c..f071ec9cc629e 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390025863.json @@ -346,6 +346,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json index 4afe87ab23a2f..14ba12f893eef 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026044.json @@ -368,6 +368,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json index e524111899ef7..b1fab5f67e059 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026648.json @@ -383,6 +383,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json index b45e553acc284..22b15ccf9e709 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/packagings-mousquetaires/products/3250390026754.json @@ -365,6 +365,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json index f37d939e21947..c3916dfad5eb4 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/3270190128403.json @@ -600,6 +600,7 @@ "en:legume", "en:lentils" ], + "ingredients_lc" : "fr", "ingredients_n" : 1, "ingredients_n_tags" : [ "1", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json index 92ca107f4d9ee..b2ab4b5e669a8 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/4270190128403.json @@ -5,11 +5,17 @@ "test" ], "added_countries_tags" : [], + "additives_n" : 0, + "additives_old_n" : 0, + "additives_old_tags" : [], + "additives_original_tags" : [], + "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(en) ", + "allergens_from_user" : "(fr) ", "allergens_hierarchy" : [], "allergens_tags" : [], + "amino_acids_tags" : [], "brands" : "Test", "brands_imported" : "Test", "brands_tags" : [ @@ -49,7 +55,7 @@ "4xxxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.3, + "completeness" : 0.4, "correctors_tags" : [], "countries" : "Etats-Unis", "countries_hierarchy" : [ @@ -66,6 +72,7 @@ "data_quality_errors_tags" : [], "data_quality_info_tags" : [ "en:no-packaging-data", + "en:ingredients-percent-analysis-ok", "en:ecoscore-extended-data-not-computed", "en:food-groups-1-unknown", "en:food-groups-2-unknown", @@ -73,20 +80,23 @@ ], "data_quality_tags" : [ "en:no-packaging-data", + "en:ingredients-percent-analysis-ok", "en:ecoscore-extended-data-not-computed", "en:food-groups-1-unknown", "en:food-groups-2-unknown", "en:food-groups-3-unknown", + "en:ingredients-unknown-score-above-0", + "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", - "en:ecoscore-production-system-no-label", - "en:ecoscore-threatened-species-ingredients-missing" + "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ + "en:ingredients-unknown-score-above-0", + "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", - "en:ecoscore-production-system-no-label", - "en:ecoscore-threatened-species-ingredients-missing" + "en:ecoscore-production-system-no-label" ], "data_sources" : "Producers, Producer - test-food-company", "data_sources_imported" : "Producers, Producer - test-food-company", @@ -315,16 +325,13 @@ "value" : 0, "warning" : "no_label" }, - "threatened_species" : { - "warning" : "ingredients_missing" - } + "threatened_species" : {} }, "agribalyse" : { "warning" : "missing_agribalyse_match" }, "missing" : { "agb_category" : 1, - "ingredients" : 1, "labels" : 1, "origins" : 1, "packagings" : 1 @@ -346,10 +353,81 @@ "informers_tags" : [ "test-user" ], + "ingredients" : [ + { + "id" : "fr:white-peaches", + "percent_estimate" : 75, + "percent_max" : 100, + "percent_min" : 50, + "text" : "White peaches" + }, + { + "id" : "fr:high-fructose-corn-syrup", + "percent_estimate" : 25, + "percent_max" : 50, + "percent_min" : 0, + "text" : "high fructose corn syrup" + } + ], + "ingredients_analysis" : { + "en:palm-oil-content-unknown" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ], + "en:vegan-status-unknown" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ], + "en:vegetarian-status-unknown" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ] + }, + "ingredients_analysis_tags" : [ + "en:palm-oil-content-unknown", + "en:vegan-status-unknown", + "en:vegetarian-status-unknown" + ], + "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_n" : 0, + "ingredients_from_palm_oil_tags" : [], + "ingredients_hierarchy" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ], + "ingredients_lc" : "fr", + "ingredients_n" : 2, + "ingredients_n_tags" : [ + "2", + "1-10" + ], + "ingredients_original_tags" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ], + "ingredients_percent_analysis" : 1, + "ingredients_tags" : [ + "fr:white-peaches", + "fr:high-fructose-corn-syrup" + ], + "ingredients_text" : "White peaches, high fructose corn syrup", "ingredients_text_fr" : "White peaches, high fructose corn syrup", "ingredients_text_fr_imported" : "White peaches, high fructose corn syrup", + "ingredients_text_with_allergens" : "White peaches, high fructose corn syrup", "ingredients_text_with_allergens_fr" : "White peaches, high fructose corn syrup", + "ingredients_that_may_be_from_palm_oil_n" : 0, + "ingredients_that_may_be_from_palm_oil_tags" : [], + "ingredients_with_specified_percent_n" : 0, + "ingredients_with_specified_percent_sum" : 0, + "ingredients_with_unspecified_percent_n" : 2, + "ingredients_with_unspecified_percent_sum" : 100, + "ingredients_without_ciqual_codes" : [ + "fr:high-fructose-corn-syrup", + "fr:white-peaches" + ], + "ingredients_without_ciqual_codes_n" : 2, "interface_version_created" : "import_csv_file - version 2019/09/17", + "known_ingredients_n" : 0, "lang" : "en", "lang_imported" : "en", "languages" : { @@ -372,6 +450,7 @@ "lc" : "en", "lc_imported" : "en", "main_countries_tags" : [], + "minerals_tags" : [], "misc_tags" : [ "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", @@ -389,11 +468,12 @@ "en:ecoscore-not-computed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group when the product does not have ingredients", - "nova_group_error" : "missing_ingredients", + "nova_group_debug" : "no nova group if too many ingredients are unknown: 2 out of 2", + "nova_group_error" : "too_many_unknown_ingredients", "nova_groups_tags" : [ "unknown" ], + "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { @@ -404,7 +484,9 @@ "energy-kj_value" : 500, "energy_100g" : 500, "energy_unit" : "kJ", - "energy_value" : 500 + "energy_value" : 500, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 }, "nutriscore_grade_producer" : "a", "nutriscore_grade_producer_imported" : "a", @@ -417,6 +499,7 @@ "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", "nutrition_score_warning_no_fiber" : 1, + "other_nutritional_substances_tags" : [], "owner" : "org-test-org", "owner_fields" : "--ignore--", "owners_tags" : "org-test-org", @@ -462,11 +545,11 @@ "url" : null } ], - "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-to-be-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-completed, en:packaging-to-be-completed, en:quantity-to-be-completed, en:product-name-to-be-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-completed, en:packaging-to-be-completed, en:quantity-to-be-completed, en:product-name-to-be-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", "en:nutrition-facts-completed", - "en:ingredients-to-be-completed", + "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", "en:characteristics-to-be-completed", @@ -481,7 +564,7 @@ "states_tags" : [ "en:to-be-completed", "en:nutrition-facts-completed", - "en:ingredients-to-be-completed", + "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", "en:characteristics-to-be-completed", @@ -495,9 +578,11 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(en) ", + "traces_from_user" : "(fr) ", "traces_hierarchy" : [], "traces_tags" : [], + "unknown_ingredients_n" : 2, "unknown_nutrients_tags" : [], + "vitamins_tags" : [], "weighers_tags" : [] } diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json index 12dc4e203a2df..bb91fd0a6187c 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/5270190128403.json @@ -369,6 +369,7 @@ "en:banana", "en:fruit" ], + "ingredients_lc" : "fr", "ingredients_n" : 1, "ingredients_n_tags" : [ "1", diff --git a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json index 93be92770caf3..7993371b587e3 100644 --- a/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json +++ b/tests/integration/expected_test_results/convert_and_import_excel_file/test/products/7270190128403.json @@ -337,6 +337,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json b/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json index 9719bc5ab77eb..f7f59d5419389 100644 --- a/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json +++ b/tests/integration/expected_test_results/data_quality_knowledge_panel/data-quality.json @@ -370,7 +370,7 @@ { "element_type" : "text", "text_element" : { - "html" : "water, test_ingredient" + "html" : "en: water, test_ingredient" } }, { diff --git a/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json b/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json index 647119ac32cf2..4a3544d20d3fd 100644 --- a/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json +++ b/tests/integration/expected_test_results/data_quality_knowledge_panel/no-data-quality.json @@ -332,7 +332,7 @@ { "element_type" : "text", "text_element" : { - "html" : "water, test_ingredient" + "html" : "en: water, test_ingredient" } }, { diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json index e5f8389616412..9b706e4500de6 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006001.json @@ -532,6 +532,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json index 7b2f304a8a728..1ad67283dc356 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006002.json @@ -347,6 +347,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json index 6a32fb022a062..4caaa3a591fe3 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006003.json @@ -342,6 +342,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json index 019fff38bcb01..505f571827798 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006004.json @@ -554,6 +554,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json index d9b4b0ed8e0cb..1a13ad7a5f8de 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006005.json @@ -357,6 +357,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json index 805beaf6a0429..bdfd59dad1664 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006006.json @@ -351,6 +351,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json index 493ae27d2a28c..e89d93d1e3066 100644 --- a/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json +++ b/tests/integration/expected_test_results/import_csv_file/replace_existing_values/3003004006007.json @@ -345,6 +345,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json index 218afc47126af..d590041ab8143 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006001.json @@ -524,6 +524,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json index 8bf7496af0e1b..7d7119066f0b4 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006002.json @@ -339,6 +339,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json index 935190d0be724..2b150a90a5cea 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006003.json @@ -342,6 +342,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "fr", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "fr", "lang_imported" : "fr", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json index 134a98d96b246..c83274d2f291e 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006004.json @@ -517,6 +517,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json index 23a65c05730b2..7c75877b9c631 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006005.json @@ -349,6 +349,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json index 1cb0c4b099d71..fc0f2653975e7 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006006.json @@ -349,6 +349,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json b/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json index eba68cc4bfcce..0891db32f35d3 100644 --- a/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json +++ b/tests/integration/expected_test_results/import_csv_file/test/2003004006007.json @@ -345,6 +345,7 @@ "informers_tags" : [ "test-user" ], + "ingredients_lc" : "en", "interface_version_created" : "import_csv_file - version 2019/09/17", "lang" : "en", "lang_imported" : "en", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json index 11680926da2f3..c464719250ac2 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2-moderator.json @@ -496,6 +496,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json index 79d16d02ced86..6ed6d4fcd8bbd 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-api-v2.json @@ -495,6 +495,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json index 3460a397f3136..29e47729ce816 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form-moderator.json @@ -500,6 +500,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json index 64b7b47306271..9104dcd247cf5 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-protected-product-web-form.json @@ -499,6 +499,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json index 26fa66408fe9d..cb5520abb8d51 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-api-v2.json @@ -494,6 +494,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json index 10dbe40597c53..dcd3090534f06 100644 --- a/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json +++ b/tests/integration/expected_test_results/protected_product/get-edited-unprotected-product-web-form.json @@ -498,6 +498,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/integration/expected_test_results/search_v1/search-no-filter.json b/tests/integration/expected_test_results/search_v1/search-no-filter.json index 726669c704292..99e719e197ab4 100644 --- a/tests/integration/expected_test_results/search_v1/search-no-filter.json +++ b/tests/integration/expected_test_results/search_v1/search-no-filter.json @@ -1,6 +1,6 @@ { "count" : 5, - "page" : 1, + "page" : "1", "page_count" : 5, "page_size" : 24, "products" : [ @@ -61,7 +61,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -94,7 +94,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : 0, + "epi_score" : "0", "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -321,21 +321,21 @@ }, { "ecoscore_material_score" : 76, - "ecoscore_shape_ratio" : 0.2, + "ecoscore_shape_ratio" : "0.2", "material" : "en:steel", "number_of_units" : 1, "shape" : "en:lid" }, { "ecoscore_material_score" : 0, - "ecoscore_shape_ratio" : 0.1, + "ecoscore_shape_ratio" : "0.1", "material" : "en:plastic", "non_recyclable_and_non_biodegradable" : "maybe", "number_of_units" : 1, "shape" : "en:film" } ], - "score" : 66.2, + "score" : "66.2", "value" : -3 }, "production_system" : { @@ -370,23 +370,23 @@ "entry_dates_tags" : "--ignore--", "food_groups_tags" : [], "forest_footprint_data" : { - "footprint_per_kg" : 0.0074375, + "footprint_per_kg" : "0.0074375", "grade" : "a", "ingredients" : [ { "conditions_tags" : [], - "footprint_per_kg" : 0.0074375, + "footprint_per_kg" : "0.0074375", "matching_tag_id" : "en:egg", - "percent" : 9.375, - "percent_estimate" : 9.375, + "percent" : "9.375", + "percent_estimate" : "9.375", "processing_factor" : 1, "tag_id" : "en:egg", "tag_type" : "ingredients", "type" : { - "deforestation_risk" : 0.68, + "deforestation_risk" : "0.68", "name" : "Oeufs Importés", - "soy_feed_factor" : 0.035, - "soy_yield" : 0.3 + "soy_feed_factor" : "0.035", + "soy_yield" : "0.3" } } ] @@ -401,7 +401,7 @@ { "ciqual_food_code" : "13050", "id" : "en:apple", - "percent_estimate" : 62.5, + "percent_estimate" : "62.5", "percent_max" : 100, "percent_min" : 25, "rank" : 1, @@ -411,7 +411,7 @@ }, { "id" : "en:milk", - "percent_estimate" : 18.75, + "percent_estimate" : "18.75", "percent_max" : 50, "percent_min" : 0, "rank" : 2, @@ -422,8 +422,8 @@ { "ciqual_food_code" : "22000", "id" : "en:egg", - "percent_estimate" : 9.375, - "percent_max" : 33.3333333333333, + "percent_estimate" : "9.375", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, "text" : "eggs", @@ -434,7 +434,7 @@ "ciqual_food_code" : "16129", "from_palm_oil" : "yes", "id" : "en:palm-oil", - "percent_estimate" : 9.375, + "percent_estimate" : "9.375", "percent_max" : 25, "percent_min" : 0, "rank" : 4, @@ -471,6 +471,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -741,7 +742,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -776,7 +777,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : 0, + "epi_score" : "0", "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -1063,6 +1064,7 @@ "en:fruit", "en:rice" ], + "ingredients_lc" : "en", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", @@ -1293,7 +1295,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -1328,7 +1330,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : 0, + "epi_score" : "0", "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -1575,23 +1577,23 @@ "entry_dates_tags" : "--ignore--", "food_groups_tags" : [], "forest_footprint_data" : { - "footprint_per_kg" : 0.0132222222222222, + "footprint_per_kg" : "0.0132222222222222", "grade" : "a", "ingredients" : [ { "conditions_tags" : [], - "footprint_per_kg" : 0.0132222222222222, + "footprint_per_kg" : "0.0132222222222222", "matching_tag_id" : "en:egg", - "percent" : 16.6666666666667, - "percent_estimate" : 16.6666666666667, + "percent" : "16.6666666666667", + "percent_estimate" : "16.6666666666667", "processing_factor" : 1, "tag_id" : "en:egg", "tag_type" : "ingredients", "type" : { - "deforestation_risk" : 0.68, + "deforestation_risk" : "0.68", "name" : "Oeufs Importés", - "soy_feed_factor" : 0.035, - "soy_yield" : 0.3 + "soy_feed_factor" : "0.035", + "soy_yield" : "0.3" } } ] @@ -1606,9 +1608,9 @@ { "ciqual_food_code" : "13050", "id" : "en:apple", - "percent_estimate" : 66.6666666666667, + "percent_estimate" : "66.6666666666667", "percent_max" : 100, - "percent_min" : 33.3333333333333, + "percent_min" : "33.3333333333333", "rank" : 1, "text" : "apple", "vegan" : "yes", @@ -1616,7 +1618,7 @@ }, { "id" : "en:milk", - "percent_estimate" : 16.6666666666667, + "percent_estimate" : "16.6666666666667", "percent_max" : 50, "percent_min" : 0, "rank" : 2, @@ -1627,8 +1629,8 @@ { "ciqual_food_code" : "22000", "id" : "en:egg", - "percent_estimate" : 16.6666666666667, - "percent_max" : 33.3333333333333, + "percent_estimate" : "16.6666666666667", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, "text" : "eggs", @@ -1657,6 +1659,7 @@ "en:dairy", "en:egg" ], + "ingredients_lc" : "en", "ingredients_n" : 3, "ingredients_n_tags" : [ "3", @@ -1745,8 +1748,8 @@ "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 33.3333333333333, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 33.3333333333333, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : "33.3333333333333", + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : "33.3333333333333", "nova-group" : 1, "nova-group_100g" : 1, "nova-group_serving" : 1 @@ -1845,7 +1848,7 @@ "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(es) ", + "allergens_from_user" : "(en) ", "allergens_hierarchy" : [], "allergens_tags" : [], "amino_acids_tags" : [], @@ -1881,7 +1884,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.5", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -1902,15 +1905,11 @@ "en:food-groups-1-unknown", "en:food-groups-2-unknown", "en:food-groups-3-unknown", - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" @@ -1920,7 +1919,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : 0, + "epi_score" : "0", "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -2141,7 +2140,10 @@ "value" : 0, "warning" : "no_label" }, - "threatened_species" : {} + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } }, "agribalyse" : { "warning" : "missing_agribalyse_match" @@ -2174,78 +2176,86 @@ ], "ingredients" : [ { - "id" : "es:apple", - "percent_estimate" : 66.6666666666667, + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : "66.6666666666667", "percent_max" : 100, - "percent_min" : 33.3333333333333, + "percent_min" : "33.3333333333333", "rank" : 1, - "text" : "apple" + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:water", - "percent_estimate" : 16.6666666666667, + "ciqual_food_code" : "18066", + "id" : "en:water", + "percent_estimate" : "16.6666666666667", "percent_max" : 50, "percent_min" : 0, "rank" : 2, - "text" : "water" + "text" : "water", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:palm-oil", - "percent_estimate" : 16.6666666666667, - "percent_max" : 33.3333333333333, + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : "16.6666666666667", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, - "text" : "palm oil" + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" } ], "ingredients_analysis" : { - "en:palm-oil-content-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" - ], - "en:vegan-status-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" - ], - "en:vegetarian-status-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:palm-oil" : [ + "en:palm-oil" ] }, "ingredients_analysis_tags" : [ - "en:palm-oil-content-unknown", - "en:vegan-status-unknown", - "en:vegetarian-status-unknown" + "en:palm-oil", + "en:vegan", + "en:vegetarian" ], "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, "ingredients_from_palm_oil_n" : 0, "ingredients_from_palm_oil_tags" : [], "ingredients_hierarchy" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:fruit", + "en:water", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 3, "ingredients_n_tags" : [ "3", "1-10" ], "ingredients_original_tags" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:water", + "en:palm-oil" ], "ingredients_percent_analysis" : 1, "ingredients_tags" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:fruit", + "en:water", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" ], "ingredients_text" : "apple, water, palm oil", "ingredients_text_en" : "apple, water, palm oil", + "ingredients_text_with_allergens" : "apple, water, palm oil", "ingredients_text_with_allergens_en" : "apple, water, palm oil", "ingredients_that_may_be_from_palm_oil_n" : 0, "ingredients_that_may_be_from_palm_oil_tags" : [], @@ -2253,15 +2263,11 @@ "ingredients_with_specified_percent_sum" : 0, "ingredients_with_unspecified_percent_n" : 3, "ingredients_with_unspecified_percent_sum" : 100, - "ingredients_without_ciqual_codes" : [ - "es:apple", - "es:palm-oil", - "es:water" - ], - "ingredients_without_ciqual_codes_n" : 3, + "ingredients_without_ciqual_codes" : [], + "ingredients_without_ciqual_codes_n" : 0, "interface_version_created" : "20150316.jqm2", "interface_version_modified" : "20150316.jqm2", - "known_ingredients_n" : 0, + "known_ingredients_n" : 7, "lang" : "es", "languages" : { "en:english" : 4 @@ -2285,7 +2291,6 @@ "main_countries_tags" : [], "minerals_tags" : [], "misc_tags" : [ - "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", "en:nutriscore-missing-nutrition-data", "en:nutriscore-missing-nutrition-data-energy", @@ -2295,6 +2300,10 @@ "en:nutriscore-missing-nutrition-data-sodium", "en:nutriscore-missing-nutrition-data-proteins", "en:nutrition-no-fiber", + "en:nutriscore-using-estimated-nutrition-facts", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-all-nutriscore-values-known", + "en:nutriscore-computed", "en:packagings-number-of-components-0", "en:packagings-not-complete", "en:packagings-empty", @@ -2302,26 +2311,121 @@ "en:ecoscore-not-computed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group if too many ingredients are unknown: 3 out of 3", - "nova_group_error" : "too_many_unknown_ingredients", + "nova_group" : 1, + "nova_group_debug" : "", + "nova_groups" : "1", + "nova_groups_markers" : {}, "nova_groups_tags" : [ - "unknown" + "en:1-unprocessed-or-minimally-processed-foods" ], "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : "33.3333333333333", + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : "33.3333333333333", + "nova-group" : 1, + "nova-group_100g" : 1, + "nova-group_serving" : 1, + "nutrition-score-fr" : 11, + "nutrition-score-fr_100g" : 11 + }, + "nutriments_estimated" : { + "alcohol_100g" : 0, + "beta-carotene_100g" : "1.13333333333333e-05", + "calcium_100g" : "0.00452166666666667", + "carbohydrates_100g" : "7.13333333333333", + "cholesterol_100g" : 0, + "copper_100g" : "2.35e-05", + "energy-kcal_100g" : "182.6", + "energy-kj_100g" : "754.666666666666", + "energy_100g" : "754.666666666666", + "fat_100g" : "16.7533333333333", + "fiber_100g" : "0.866666666666667", + "fructose_100g" : "4.02", + "galactose_100g" : 0, + "glucose_100g" : "2.16666666666667", + "iodine_100g" : "9.66666666666666e-07", + "iron_100g" : "5.33333333333333e-05", + "lactose_100g" : 0, + "magnesium_100g" : "0.00283166666666667", + "maltose_100g" : 0, + "manganese_100g" : "2.5595e-05", + "pantothenic-acid_100g" : "4.73333333333333e-05", + "phosphorus_100g" : "0.00733333333333333", + "phylloquinone_100g" : "1.73333333333333e-06", + "polyols_100g" : "0.393333333333333", + "potassium_100g" : "0.0601216666666667", + "proteins_100g" : "0.18", + "salt_100g" : "0.00126666666666667", + "saturated-fat_100g" : "8.23066666666666", + "selenium_100g" : "1.43333333333333e-06", + "sodium_100g" : "0.0004", + "starch_100g" : 0, + "sucrose_100g" : "0.546666666666667", + "sugars_100g" : "6.73333333333333", + "vitamin-a_100g" : 0, + "vitamin-b12_100g" : 0, + "vitamin-b1_100g" : "1.26666666666667e-05", + "vitamin-b2_100g" : "1.86666666666667e-05", + "vitamin-b6_100g" : "2.46666666666667e-05", + "vitamin-b9_100g" : 0, + "vitamin-c_100g" : "0.00266666666666667", + "vitamin-d_100g" : 0, + "vitamin-e_100g" : "0.00268333333333333", + "vitamin-pp_100g" : "6.06666666666667e-05", + "water_100g" : "74.4666666666667", + "zinc_100g" : "3.51666666666667e-05" + }, + "nutriscore_data" : { + "energy" : "754.666666666666", + "energy_points" : 2, + "energy_value" : "754.7", + "fiber" : "0.866666666666667", + "fiber_points" : 0, + "fiber_value" : "0.87", + "fruits_vegetables_nuts_colza_walnut_olive_oils" : "33.3333333333333", + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : "33.3", + "grade" : "d", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 11, + "positive_points" : 0, + "proteins" : "0.18", + "proteins_points" : 0, + "proteins_value" : "0.18", + "saturated_fat" : "8.23066666666666", + "saturated_fat_points" : 8, + "saturated_fat_ratio" : "49.1285316354954", + "saturated_fat_ratio_points" : 7, + "saturated_fat_ratio_value" : "49.1", + "saturated_fat_value" : "8.2", + "score" : 11, + "sodium" : "0.4", + "sodium_points" : 0, + "sodium_value" : "0.4", + "sugars" : "6.73333333333333", + "sugars_points" : 1, + "sugars_value" : "6.73" }, + "nutriscore_grade" : "d", + "nutriscore_score" : 11, + "nutriscore_score_opposite" : -11, "nutrition_data_per" : "100g", "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "d", + "nutrition_grades" : "d", "nutrition_grades_tags" : [ - "unknown" + "d" ], "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", - "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : "33.3333333333333", + "nutrition_score_warning_nutriments_estimated" : 1, "origin" : "spain", "origin_en" : "spain", "other_nutritional_substances_tags" : [], @@ -2350,10 +2454,10 @@ "rev" : 1, "serving_quantity" : 10, "serving_size" : "10 g", - "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -2368,7 +2472,7 @@ ], "states_tags" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -2383,10 +2487,10 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(es) ", + "traces_from_user" : "(en) ", "traces_hierarchy" : [], "traces_tags" : [], - "unknown_ingredients_n" : 3, + "unknown_ingredients_n" : 0, "unknown_nutrients_tags" : [], "url" : "http://world.openfoodfacts.localhost/product/200000000039/vegan-test-snack", "vitamins_tags" : [], @@ -2410,7 +2514,7 @@ "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(es) ", + "allergens_from_user" : "(en) ", "allergens_hierarchy" : [], "allergens_tags" : [], "amino_acids_tags" : [], @@ -2462,7 +2566,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.5", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -2483,15 +2587,11 @@ "en:food-groups-1-known", "en:food-groups-2-known", "en:food-groups-3-unknown", - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" @@ -2501,7 +2601,7 @@ "origins_of_ingredients" : { "aggregated_origins" : [ { - "epi_score" : 0, + "epi_score" : "0", "origin" : "en:unknown", "percent" : 100, "transportation_score" : null @@ -2726,22 +2826,22 @@ }, "agribalyse" : { "agribalyse_proxy_food_code" : "32135", - "co2_agriculture" : 2.2396004, + "co2_agriculture" : "2.2396004", "co2_consumption" : 0, - "co2_distribution" : 0.019530673, - "co2_packaging" : 0.28159592, - "co2_processing" : 0.77051126, - "co2_total" : 3.564111983, - "co2_transportation" : 0.25287373, + "co2_distribution" : "0.019530673", + "co2_packaging" : "0.28159592", + "co2_processing" : "0.77051126", + "co2_total" : "3.564111983", + "co2_transportation" : "0.25287373", "code" : "32135", "dqr" : "4.03", - "ef_agriculture" : 0.50064279, + "ef_agriculture" : "0.50064279", "ef_consumption" : 0, - "ef_distribution" : 0.0048315303, - "ef_packaging" : 0.023715692, - "ef_processing" : 0.078716079, - "ef_total" : 0.6323498093, - "ef_transportation" : 0.024443718, + "ef_distribution" : "0.0048315303", + "ef_packaging" : "0.023715692", + "ef_processing" : "0.078716079", + "ef_total" : "0.6323498093", + "ef_transportation" : "0.024443718", "is_beverage" : 0, "name_en" : "Breakfast cereals, mix of puffed or extruded cereals, fortified with vitamins and chemical elements", "name_fr" : "Multi-céréales soufflées ou extrudées, enrichies en vitamines et minéraux", @@ -2911,64 +3011,61 @@ ], "ingredients" : [ { - "id" : "es:apple", + "ciqual_food_code" : "13050", + "id" : "en:apple", "percent_estimate" : 75, "percent_max" : 100, "percent_min" : 50, "rank" : 1, - "text" : "apple" + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:water", + "ciqual_food_code" : "18066", + "id" : "en:water", "percent_estimate" : 25, "percent_max" : 50, "percent_min" : 0, "rank" : 2, - "text" : "water" + "text" : "water", + "vegan" : "yes", + "vegetarian" : "yes" } ], - "ingredients_analysis" : { - "en:palm-oil-content-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegan-status-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegetarian-status-unknown" : [ - "es:apple", - "es:water" - ] - }, + "ingredients_analysis" : {}, "ingredients_analysis_tags" : [ - "en:palm-oil-content-unknown", - "en:vegan-status-unknown", - "en:vegetarian-status-unknown" + "en:palm-oil-free", + "en:vegan", + "en:vegetarian" ], "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, "ingredients_from_palm_oil_n" : 0, "ingredients_from_palm_oil_tags" : [], "ingredients_hierarchy" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], + "ingredients_lc" : "en", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", "1-10" ], "ingredients_original_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:water" ], "ingredients_percent_analysis" : 1, "ingredients_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], "ingredients_text" : "apple, water", "ingredients_text_en" : "apple, water", + "ingredients_text_with_allergens" : "apple, water", "ingredients_text_with_allergens_en" : "apple, water", "ingredients_that_may_be_from_palm_oil_n" : 0, "ingredients_that_may_be_from_palm_oil_tags" : [], @@ -2976,14 +3073,11 @@ "ingredients_with_specified_percent_sum" : 0, "ingredients_with_unspecified_percent_n" : 2, "ingredients_with_unspecified_percent_sum" : 100, - "ingredients_without_ciqual_codes" : [ - "es:apple", - "es:water" - ], - "ingredients_without_ciqual_codes_n" : 2, + "ingredients_without_ciqual_codes" : [], + "ingredients_without_ciqual_codes_n" : 0, "interface_version_created" : "20150316.jqm2", "interface_version_modified" : "20150316.jqm2", - "known_ingredients_n" : 0, + "known_ingredients_n" : 3, "lang" : "es", "languages" : { "en:english" : 5 @@ -3007,7 +3101,6 @@ "main_countries_tags" : [], "minerals_tags" : [], "misc_tags" : [ - "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", "en:nutriscore-missing-nutrition-data", "en:nutriscore-missing-nutrition-data-energy", @@ -3017,6 +3110,10 @@ "en:nutriscore-missing-nutrition-data-sodium", "en:nutriscore-missing-nutrition-data-proteins", "en:nutrition-no-fiber", + "en:nutriscore-using-estimated-nutrition-facts", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-all-nutriscore-values-known", + "en:nutriscore-computed", "en:packagings-number-of-components-0", "en:packagings-not-complete", "en:packagings-empty", @@ -3031,26 +3128,121 @@ "en:ecoscore-grade-changed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group if too many ingredients are unknown: 2 out of 2", - "nova_group_error" : "too_many_unknown_ingredients", + "nova_group" : 1, + "nova_group_debug" : "", + "nova_groups" : "1", + "nova_groups_markers" : {}, "nova_groups_tags" : [ - "unknown" + "en:1-unprocessed-or-minimally-processed-foods" ], "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50, + "nova-group" : 1, + "nova-group_100g" : 1, + "nova-group_serving" : 1, + "nutrition-score-fr" : -1, + "nutrition-score-fr_100g" : -1 + }, + "nutriments_estimated" : { + "alcohol_100g" : 0, + "beta-carotene_100g" : "1.275e-05", + "calcium_100g" : "0.0055325", + "carbohydrates_100g" : "8.025", + "cholesterol_100g" : 0, + "copper_100g" : "2.75e-05", + "energy-kcal_100g" : "36.675", + "energy-kj_100g" : "155.25", + "energy_100g" : "155.25", + "fat_100g" : "0.0975", + "fiber_100g" : "0.975", + "fructose_100g" : "4.5225", + "galactose_100g" : 0, + "glucose_100g" : "2.4375", + "iodine_100g" : "7.5e-08", + "iron_100g" : "6e-05", + "lactose_100g" : 0, + "magnesium_100g" : "0.0032475", + "maltose_100g" : 0, + "manganese_100g" : "2.8705e-05", + "pantothenic-acid_100g" : "5.325e-05", + "phosphorus_100g" : "0.00825", + "phylloquinone_100g" : "4.5e-07", + "polyols_100g" : "0.4425", + "potassium_100g" : "0.0676825", + "proteins_100g" : "0.2025", + "salt_100g" : "0.0019", + "saturated-fat_100g" : "0.01575", + "selenium_100g" : "2.375e-07", + "sodium_100g" : "0.0006", + "starch_100g" : 0, + "sucrose_100g" : "0.615", + "sugars_100g" : "7.575", + "vitamin-a_100g" : 0, + "vitamin-b12_100g" : 0, + "vitamin-b1_100g" : "1.425e-05", + "vitamin-b2_100g" : "2.1e-05", + "vitamin-b6_100g" : "2.775e-05", + "vitamin-b9_100g" : 0, + "vitamin-c_100g" : "0.003", + "vitamin-d_100g" : 0, + "vitamin-e_100g" : "3.75e-05", + "vitamin-pp_100g" : "6.825e-05", + "water_100g" : "90.025", + "zinc_100g" : "4.025e-05" }, + "nutriscore_data" : { + "energy" : "155.25", + "energy_points" : 0, + "energy_value" : "155.3", + "fiber" : "0.975", + "fiber_points" : 1, + "fiber_value" : "0.98", + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50, + "grade" : "a", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 1, + "positive_points" : 2, + "proteins" : "0.2025", + "proteins_points" : 0, + "proteins_value" : "0.2", + "saturated_fat" : "0.01575", + "saturated_fat_points" : 0, + "saturated_fat_ratio" : "16.1538461538462", + "saturated_fat_ratio_points" : 2, + "saturated_fat_ratio_value" : "16.2", + "saturated_fat_value" : 0, + "score" : -1, + "sodium" : "0.6", + "sodium_points" : 0, + "sodium_value" : "0.6", + "sugars" : "7.575", + "sugars_points" : 1, + "sugars_value" : "7.58" + }, + "nutriscore_grade" : "a", + "nutriscore_score" : -1, + "nutriscore_score_opposite" : 1, "nutrition_data_per" : "100g", "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "a", + "nutrition_grades" : "a", "nutrition_grades_tags" : [ - "unknown" + "a" ], "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", - "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50, + "nutrition_score_warning_nutriments_estimated" : 1, "origin" : "China", "origin_en" : "China", "other_nutritional_substances_tags" : [], @@ -3081,10 +3273,10 @@ "rev" : 1, "serving_quantity" : 10, "serving_size" : "10 g", - "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -3099,7 +3291,7 @@ ], "states_tags" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -3114,10 +3306,10 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(es) ", + "traces_from_user" : "(en) ", "traces_hierarchy" : [], "traces_tags" : [], - "unknown_ingredients_n" : 2, + "unknown_ingredients_n" : 0, "unknown_nutrients_tags" : [], "url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-test-snack", "vitamins_tags" : [], diff --git a/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json b/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json index 122db70b778e4..54308bfe2536a 100644 --- a/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json +++ b/tests/integration/expected_test_results/search_v1/search-tags-categories-without-ingredients-from-palm-oil.json @@ -1,6 +1,6 @@ { "count" : 1, - "page" : 1, + "page" : "1", "page_count" : 1, "page_size" : 24, "products" : [ @@ -22,7 +22,7 @@ "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(es) ", + "allergens_from_user" : "(en) ", "allergens_hierarchy" : [], "allergens_tags" : [], "amino_acids_tags" : [], @@ -74,7 +74,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.5", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -95,15 +95,11 @@ "en:food-groups-1-known", "en:food-groups-2-known", "en:food-groups-3-unknown", - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" @@ -338,22 +334,22 @@ }, "agribalyse" : { "agribalyse_proxy_food_code" : "32135", - "co2_agriculture" : 2.2396004, + "co2_agriculture" : "2.2396004", "co2_consumption" : 0, - "co2_distribution" : 0.019530673, - "co2_packaging" : 0.28159592, - "co2_processing" : 0.77051126, - "co2_total" : 3.564111983, - "co2_transportation" : 0.25287373, + "co2_distribution" : "0.019530673", + "co2_packaging" : "0.28159592", + "co2_processing" : "0.77051126", + "co2_total" : "3.564111983", + "co2_transportation" : "0.25287373", "code" : "32135", "dqr" : "4.03", - "ef_agriculture" : 0.50064279, + "ef_agriculture" : "0.50064279", "ef_consumption" : 0, - "ef_distribution" : 0.0048315303, - "ef_packaging" : 0.023715692, - "ef_processing" : 0.078716079, - "ef_total" : 0.6323498093, - "ef_transportation" : 0.024443718, + "ef_distribution" : "0.0048315303", + "ef_packaging" : "0.023715692", + "ef_processing" : "0.078716079", + "ef_total" : "0.6323498093", + "ef_transportation" : "0.024443718", "is_beverage" : 0, "name_en" : "Breakfast cereals, mix of puffed or extruded cereals, fortified with vitamins and chemical elements", "name_fr" : "Multi-céréales soufflées ou extrudées, enrichies en vitamines et minéraux", @@ -523,64 +519,61 @@ ], "ingredients" : [ { - "id" : "es:apple", + "ciqual_food_code" : "13050", + "id" : "en:apple", "percent_estimate" : 75, "percent_max" : 100, "percent_min" : 50, "rank" : 1, - "text" : "apple" + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:water", + "ciqual_food_code" : "18066", + "id" : "en:water", "percent_estimate" : 25, "percent_max" : 50, "percent_min" : 0, "rank" : 2, - "text" : "water" + "text" : "water", + "vegan" : "yes", + "vegetarian" : "yes" } ], - "ingredients_analysis" : { - "en:palm-oil-content-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegan-status-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegetarian-status-unknown" : [ - "es:apple", - "es:water" - ] - }, + "ingredients_analysis" : {}, "ingredients_analysis_tags" : [ - "en:palm-oil-content-unknown", - "en:vegan-status-unknown", - "en:vegetarian-status-unknown" + "en:palm-oil-free", + "en:vegan", + "en:vegetarian" ], "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, "ingredients_from_palm_oil_n" : 0, "ingredients_from_palm_oil_tags" : [], "ingredients_hierarchy" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], + "ingredients_lc" : "en", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", "1-10" ], "ingredients_original_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:water" ], "ingredients_percent_analysis" : 1, "ingredients_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], "ingredients_text" : "apple, water", "ingredients_text_en" : "apple, water", + "ingredients_text_with_allergens" : "apple, water", "ingredients_text_with_allergens_en" : "apple, water", "ingredients_that_may_be_from_palm_oil_n" : 0, "ingredients_that_may_be_from_palm_oil_tags" : [], @@ -588,14 +581,11 @@ "ingredients_with_specified_percent_sum" : 0, "ingredients_with_unspecified_percent_n" : 2, "ingredients_with_unspecified_percent_sum" : 100, - "ingredients_without_ciqual_codes" : [ - "es:apple", - "es:water" - ], - "ingredients_without_ciqual_codes_n" : 2, + "ingredients_without_ciqual_codes" : [], + "ingredients_without_ciqual_codes_n" : 0, "interface_version_created" : "20150316.jqm2", "interface_version_modified" : "20150316.jqm2", - "known_ingredients_n" : 0, + "known_ingredients_n" : 3, "lang" : "es", "languages" : { "en:english" : 5 @@ -619,7 +609,6 @@ "main_countries_tags" : [], "minerals_tags" : [], "misc_tags" : [ - "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", "en:nutriscore-missing-nutrition-data", "en:nutriscore-missing-nutrition-data-energy", @@ -629,6 +618,10 @@ "en:nutriscore-missing-nutrition-data-sodium", "en:nutriscore-missing-nutrition-data-proteins", "en:nutrition-no-fiber", + "en:nutriscore-using-estimated-nutrition-facts", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-all-nutriscore-values-known", + "en:nutriscore-computed", "en:packagings-number-of-components-0", "en:packagings-not-complete", "en:packagings-empty", @@ -643,26 +636,121 @@ "en:ecoscore-grade-changed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group if too many ingredients are unknown: 2 out of 2", - "nova_group_error" : "too_many_unknown_ingredients", + "nova_group" : 1, + "nova_group_debug" : "", + "nova_groups" : "1", + "nova_groups_markers" : {}, "nova_groups_tags" : [ - "unknown" + "en:1-unprocessed-or-minimally-processed-foods" ], "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50, + "nova-group" : 1, + "nova-group_100g" : 1, + "nova-group_serving" : 1, + "nutrition-score-fr" : -1, + "nutrition-score-fr_100g" : -1 + }, + "nutriments_estimated" : { + "alcohol_100g" : 0, + "beta-carotene_100g" : "1.275e-05", + "calcium_100g" : "0.0055325", + "carbohydrates_100g" : "8.025", + "cholesterol_100g" : 0, + "copper_100g" : "2.75e-05", + "energy-kcal_100g" : "36.675", + "energy-kj_100g" : "155.25", + "energy_100g" : "155.25", + "fat_100g" : "0.0975", + "fiber_100g" : "0.975", + "fructose_100g" : "4.5225", + "galactose_100g" : 0, + "glucose_100g" : "2.4375", + "iodine_100g" : "7.5e-08", + "iron_100g" : "6e-05", + "lactose_100g" : 0, + "magnesium_100g" : "0.0032475", + "maltose_100g" : 0, + "manganese_100g" : "2.8705e-05", + "pantothenic-acid_100g" : "5.325e-05", + "phosphorus_100g" : "0.00825", + "phylloquinone_100g" : "4.5e-07", + "polyols_100g" : "0.4425", + "potassium_100g" : "0.0676825", + "proteins_100g" : "0.2025", + "salt_100g" : "0.0019", + "saturated-fat_100g" : "0.01575", + "selenium_100g" : "2.375e-07", + "sodium_100g" : "0.0006", + "starch_100g" : 0, + "sucrose_100g" : "0.615", + "sugars_100g" : "7.575", + "vitamin-a_100g" : 0, + "vitamin-b12_100g" : 0, + "vitamin-b1_100g" : "1.425e-05", + "vitamin-b2_100g" : "2.1e-05", + "vitamin-b6_100g" : "2.775e-05", + "vitamin-b9_100g" : 0, + "vitamin-c_100g" : "0.003", + "vitamin-d_100g" : 0, + "vitamin-e_100g" : "3.75e-05", + "vitamin-pp_100g" : "6.825e-05", + "water_100g" : "90.025", + "zinc_100g" : "4.025e-05" + }, + "nutriscore_data" : { + "energy" : "155.25", + "energy_points" : 0, + "energy_value" : "155.3", + "fiber" : "0.975", + "fiber_points" : 1, + "fiber_value" : "0.98", + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50, + "grade" : "a", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 1, + "positive_points" : 2, + "proteins" : "0.2025", + "proteins_points" : 0, + "proteins_value" : "0.2", + "saturated_fat" : "0.01575", + "saturated_fat_points" : 0, + "saturated_fat_ratio" : "16.1538461538462", + "saturated_fat_ratio_points" : 2, + "saturated_fat_ratio_value" : "16.2", + "saturated_fat_value" : 0, + "score" : -1, + "sodium" : "0.6", + "sodium_points" : 0, + "sodium_value" : "0.6", + "sugars" : "7.575", + "sugars_points" : 1, + "sugars_value" : "7.58" }, + "nutriscore_grade" : "a", + "nutriscore_score" : -1, + "nutriscore_score_opposite" : 1, "nutrition_data_per" : "100g", "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "a", + "nutrition_grades" : "a", "nutrition_grades_tags" : [ - "unknown" + "a" ], "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", - "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50, + "nutrition_score_warning_nutriments_estimated" : 1, "origin" : "China", "origin_en" : "China", "other_nutritional_substances_tags" : [], @@ -693,10 +781,10 @@ "rev" : 1, "serving_quantity" : 10, "serving_size" : "10 g", - "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -711,7 +799,7 @@ ], "states_tags" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -726,10 +814,10 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(es) ", + "traces_from_user" : "(en) ", "traces_hierarchy" : [], "traces_tags" : [], - "unknown_ingredients_n" : 2, + "unknown_ingredients_n" : 0, "unknown_nutrients_tags" : [], "url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-test-snack", "vitamins_tags" : [], diff --git a/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json b/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json index 726669c704292..d15d68c40923f 100644 --- a/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json +++ b/tests/integration/expected_test_results/search_v1/search-without-ingredients-from-palm-oil.json @@ -1,6 +1,6 @@ { "count" : 5, - "page" : 1, + "page" : "1", "page_count" : 5, "page_size" : 24, "products" : [ @@ -61,7 +61,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -321,21 +321,21 @@ }, { "ecoscore_material_score" : 76, - "ecoscore_shape_ratio" : 0.2, + "ecoscore_shape_ratio" : "0.2", "material" : "en:steel", "number_of_units" : 1, "shape" : "en:lid" }, { "ecoscore_material_score" : 0, - "ecoscore_shape_ratio" : 0.1, + "ecoscore_shape_ratio" : "0.1", "material" : "en:plastic", "non_recyclable_and_non_biodegradable" : "maybe", "number_of_units" : 1, "shape" : "en:film" } ], - "score" : 66.2, + "score" : "66.2", "value" : -3 }, "production_system" : { @@ -370,23 +370,23 @@ "entry_dates_tags" : "--ignore--", "food_groups_tags" : [], "forest_footprint_data" : { - "footprint_per_kg" : 0.0074375, + "footprint_per_kg" : "0.0074375", "grade" : "a", "ingredients" : [ { "conditions_tags" : [], - "footprint_per_kg" : 0.0074375, + "footprint_per_kg" : "0.0074375", "matching_tag_id" : "en:egg", - "percent" : 9.375, - "percent_estimate" : 9.375, + "percent" : "9.375", + "percent_estimate" : "9.375", "processing_factor" : 1, "tag_id" : "en:egg", "tag_type" : "ingredients", "type" : { - "deforestation_risk" : 0.68, + "deforestation_risk" : "0.68", "name" : "Oeufs Importés", - "soy_feed_factor" : 0.035, - "soy_yield" : 0.3 + "soy_feed_factor" : "0.035", + "soy_yield" : "0.3" } } ] @@ -401,7 +401,7 @@ { "ciqual_food_code" : "13050", "id" : "en:apple", - "percent_estimate" : 62.5, + "percent_estimate" : "62.5", "percent_max" : 100, "percent_min" : 25, "rank" : 1, @@ -411,7 +411,7 @@ }, { "id" : "en:milk", - "percent_estimate" : 18.75, + "percent_estimate" : "18.75", "percent_max" : 50, "percent_min" : 0, "rank" : 2, @@ -422,8 +422,8 @@ { "ciqual_food_code" : "22000", "id" : "en:egg", - "percent_estimate" : 9.375, - "percent_max" : 33.3333333333333, + "percent_estimate" : "9.375", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, "text" : "eggs", @@ -434,7 +434,7 @@ "ciqual_food_code" : "16129", "from_palm_oil" : "yes", "id" : "en:palm-oil", - "percent_estimate" : 9.375, + "percent_estimate" : "9.375", "percent_max" : 25, "percent_min" : 0, "rank" : 4, @@ -471,6 +471,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", @@ -741,7 +742,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -1063,6 +1064,7 @@ "en:fruit", "en:rice" ], + "ingredients_lc" : "en", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", @@ -1293,7 +1295,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.4", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -1575,23 +1577,23 @@ "entry_dates_tags" : "--ignore--", "food_groups_tags" : [], "forest_footprint_data" : { - "footprint_per_kg" : 0.0132222222222222, + "footprint_per_kg" : "0.0132222222222222", "grade" : "a", "ingredients" : [ { "conditions_tags" : [], - "footprint_per_kg" : 0.0132222222222222, + "footprint_per_kg" : "0.0132222222222222", "matching_tag_id" : "en:egg", - "percent" : 16.6666666666667, - "percent_estimate" : 16.6666666666667, + "percent" : "16.6666666666667", + "percent_estimate" : "16.6666666666667", "processing_factor" : 1, "tag_id" : "en:egg", "tag_type" : "ingredients", "type" : { - "deforestation_risk" : 0.68, + "deforestation_risk" : "0.68", "name" : "Oeufs Importés", - "soy_feed_factor" : 0.035, - "soy_yield" : 0.3 + "soy_feed_factor" : "0.035", + "soy_yield" : "0.3" } } ] @@ -1606,9 +1608,9 @@ { "ciqual_food_code" : "13050", "id" : "en:apple", - "percent_estimate" : 66.6666666666667, + "percent_estimate" : "66.6666666666667", "percent_max" : 100, - "percent_min" : 33.3333333333333, + "percent_min" : "33.3333333333333", "rank" : 1, "text" : "apple", "vegan" : "yes", @@ -1616,7 +1618,7 @@ }, { "id" : "en:milk", - "percent_estimate" : 16.6666666666667, + "percent_estimate" : "16.6666666666667", "percent_max" : 50, "percent_min" : 0, "rank" : 2, @@ -1627,8 +1629,8 @@ { "ciqual_food_code" : "22000", "id" : "en:egg", - "percent_estimate" : 16.6666666666667, - "percent_max" : 33.3333333333333, + "percent_estimate" : "16.6666666666667", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, "text" : "eggs", @@ -1657,6 +1659,7 @@ "en:dairy", "en:egg" ], + "ingredients_lc" : "en", "ingredients_n" : 3, "ingredients_n_tags" : [ "3", @@ -1745,8 +1748,8 @@ "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 33.3333333333333, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 33.3333333333333, + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : "33.3333333333333", + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : "33.3333333333333", "nova-group" : 1, "nova-group_100g" : 1, "nova-group_serving" : 1 @@ -1845,7 +1848,7 @@ "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(es) ", + "allergens_from_user" : "(en) ", "allergens_hierarchy" : [], "allergens_tags" : [], "amino_acids_tags" : [], @@ -1881,7 +1884,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.5", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -1902,15 +1905,11 @@ "en:food-groups-1-unknown", "en:food-groups-2-unknown", "en:food-groups-3-unknown", - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" @@ -2141,7 +2140,10 @@ "value" : 0, "warning" : "no_label" }, - "threatened_species" : {} + "threatened_species" : { + "ingredient" : "en:palm-oil", + "value" : -10 + } }, "agribalyse" : { "warning" : "missing_agribalyse_match" @@ -2174,78 +2176,86 @@ ], "ingredients" : [ { - "id" : "es:apple", - "percent_estimate" : 66.6666666666667, + "ciqual_food_code" : "13050", + "id" : "en:apple", + "percent_estimate" : "66.6666666666667", "percent_max" : 100, - "percent_min" : 33.3333333333333, + "percent_min" : "33.3333333333333", "rank" : 1, - "text" : "apple" + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:water", - "percent_estimate" : 16.6666666666667, + "ciqual_food_code" : "18066", + "id" : "en:water", + "percent_estimate" : "16.6666666666667", "percent_max" : 50, "percent_min" : 0, "rank" : 2, - "text" : "water" + "text" : "water", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:palm-oil", - "percent_estimate" : 16.6666666666667, - "percent_max" : 33.3333333333333, + "ciqual_food_code" : "16129", + "from_palm_oil" : "yes", + "id" : "en:palm-oil", + "percent_estimate" : "16.6666666666667", + "percent_max" : "33.3333333333333", "percent_min" : 0, "rank" : 3, - "text" : "palm oil" + "text" : "palm oil", + "vegan" : "yes", + "vegetarian" : "yes" } ], "ingredients_analysis" : { - "en:palm-oil-content-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" - ], - "en:vegan-status-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" - ], - "en:vegetarian-status-unknown" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:palm-oil" : [ + "en:palm-oil" ] }, "ingredients_analysis_tags" : [ - "en:palm-oil-content-unknown", - "en:vegan-status-unknown", - "en:vegetarian-status-unknown" + "en:palm-oil", + "en:vegan", + "en:vegetarian" ], "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, "ingredients_from_palm_oil_n" : 0, "ingredients_from_palm_oil_tags" : [], "ingredients_hierarchy" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:fruit", + "en:water", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" ], + "ingredients_lc" : "en", "ingredients_n" : 3, "ingredients_n_tags" : [ "3", "1-10" ], "ingredients_original_tags" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:water", + "en:palm-oil" ], "ingredients_percent_analysis" : 1, "ingredients_tags" : [ - "es:apple", - "es:water", - "es:palm-oil" + "en:apple", + "en:fruit", + "en:water", + "en:palm-oil", + "en:oil-and-fat", + "en:vegetable-oil-and-fat", + "en:palm-oil-and-fat" ], "ingredients_text" : "apple, water, palm oil", "ingredients_text_en" : "apple, water, palm oil", + "ingredients_text_with_allergens" : "apple, water, palm oil", "ingredients_text_with_allergens_en" : "apple, water, palm oil", "ingredients_that_may_be_from_palm_oil_n" : 0, "ingredients_that_may_be_from_palm_oil_tags" : [], @@ -2253,15 +2263,11 @@ "ingredients_with_specified_percent_sum" : 0, "ingredients_with_unspecified_percent_n" : 3, "ingredients_with_unspecified_percent_sum" : 100, - "ingredients_without_ciqual_codes" : [ - "es:apple", - "es:palm-oil", - "es:water" - ], - "ingredients_without_ciqual_codes_n" : 3, + "ingredients_without_ciqual_codes" : [], + "ingredients_without_ciqual_codes_n" : 0, "interface_version_created" : "20150316.jqm2", "interface_version_modified" : "20150316.jqm2", - "known_ingredients_n" : 0, + "known_ingredients_n" : 7, "lang" : "es", "languages" : { "en:english" : 4 @@ -2285,7 +2291,6 @@ "main_countries_tags" : [], "minerals_tags" : [], "misc_tags" : [ - "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", "en:nutriscore-missing-nutrition-data", "en:nutriscore-missing-nutrition-data-energy", @@ -2295,6 +2300,10 @@ "en:nutriscore-missing-nutrition-data-sodium", "en:nutriscore-missing-nutrition-data-proteins", "en:nutrition-no-fiber", + "en:nutriscore-using-estimated-nutrition-facts", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-all-nutriscore-values-known", + "en:nutriscore-computed", "en:packagings-number-of-components-0", "en:packagings-not-complete", "en:packagings-empty", @@ -2302,26 +2311,121 @@ "en:ecoscore-not-computed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group if too many ingredients are unknown: 3 out of 3", - "nova_group_error" : "too_many_unknown_ingredients", + "nova_group" : 1, + "nova_group_debug" : "", + "nova_groups" : "1", + "nova_groups_markers" : {}, "nova_groups_tags" : [ - "unknown" + "en:1-unprocessed-or-minimally-processed-foods" ], "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : "33.3333333333333", + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : "33.3333333333333", + "nova-group" : 1, + "nova-group_100g" : 1, + "nova-group_serving" : 1, + "nutrition-score-fr" : 11, + "nutrition-score-fr_100g" : 11 + }, + "nutriments_estimated" : { + "alcohol_100g" : 0, + "beta-carotene_100g" : "1.13333333333333e-05", + "calcium_100g" : "0.00452166666666667", + "carbohydrates_100g" : "7.13333333333333", + "cholesterol_100g" : 0, + "copper_100g" : "2.35e-05", + "energy-kcal_100g" : "182.6", + "energy-kj_100g" : "754.666666666666", + "energy_100g" : "754.666666666666", + "fat_100g" : "16.7533333333333", + "fiber_100g" : "0.866666666666667", + "fructose_100g" : "4.02", + "galactose_100g" : 0, + "glucose_100g" : "2.16666666666667", + "iodine_100g" : "9.66666666666666e-07", + "iron_100g" : "5.33333333333333e-05", + "lactose_100g" : 0, + "magnesium_100g" : "0.00283166666666667", + "maltose_100g" : 0, + "manganese_100g" : "2.5595e-05", + "pantothenic-acid_100g" : "4.73333333333333e-05", + "phosphorus_100g" : "0.00733333333333333", + "phylloquinone_100g" : "1.73333333333333e-06", + "polyols_100g" : "0.393333333333333", + "potassium_100g" : "0.0601216666666667", + "proteins_100g" : "0.18", + "salt_100g" : "0.00126666666666667", + "saturated-fat_100g" : "8.23066666666666", + "selenium_100g" : "1.43333333333333e-06", + "sodium_100g" : "0.0004", + "starch_100g" : 0, + "sucrose_100g" : "0.546666666666667", + "sugars_100g" : "6.73333333333333", + "vitamin-a_100g" : 0, + "vitamin-b12_100g" : 0, + "vitamin-b1_100g" : "1.26666666666667e-05", + "vitamin-b2_100g" : "1.86666666666667e-05", + "vitamin-b6_100g" : "2.46666666666667e-05", + "vitamin-b9_100g" : 0, + "vitamin-c_100g" : "0.00266666666666667", + "vitamin-d_100g" : 0, + "vitamin-e_100g" : "0.00268333333333333", + "vitamin-pp_100g" : "6.06666666666667e-05", + "water_100g" : "74.4666666666667", + "zinc_100g" : "3.51666666666667e-05" + }, + "nutriscore_data" : { + "energy" : "754.666666666666", + "energy_points" : 2, + "energy_value" : "754.7", + "fiber" : "0.866666666666667", + "fiber_points" : 0, + "fiber_value" : "0.87", + "fruits_vegetables_nuts_colza_walnut_olive_oils" : "33.3333333333333", + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 0, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : "33.3", + "grade" : "d", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 11, + "positive_points" : 0, + "proteins" : "0.18", + "proteins_points" : 0, + "proteins_value" : "0.18", + "saturated_fat" : "8.23066666666666", + "saturated_fat_points" : 8, + "saturated_fat_ratio" : "49.1285316354954", + "saturated_fat_ratio_points" : 7, + "saturated_fat_ratio_value" : "49.1", + "saturated_fat_value" : "8.2", + "score" : 11, + "sodium" : "0.4", + "sodium_points" : 0, + "sodium_value" : "0.4", + "sugars" : "6.73333333333333", + "sugars_points" : 1, + "sugars_value" : "6.73" }, + "nutriscore_grade" : "d", + "nutriscore_score" : 11, + "nutriscore_score_opposite" : -11, "nutrition_data_per" : "100g", "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "d", + "nutrition_grades" : "d", "nutrition_grades_tags" : [ - "unknown" + "d" ], "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", - "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : "33.3333333333333", + "nutrition_score_warning_nutriments_estimated" : 1, "origin" : "spain", "origin_en" : "spain", "other_nutritional_substances_tags" : [], @@ -2350,10 +2454,10 @@ "rev" : 1, "serving_quantity" : 10, "serving_size" : "10 g", - "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -2368,7 +2472,7 @@ ], "states_tags" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -2383,10 +2487,10 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(es) ", + "traces_from_user" : "(en) ", "traces_hierarchy" : [], "traces_tags" : [], - "unknown_ingredients_n" : 3, + "unknown_ingredients_n" : 0, "unknown_nutrients_tags" : [], "url" : "http://world.openfoodfacts.localhost/product/200000000039/vegan-test-snack", "vitamins_tags" : [], @@ -2410,7 +2514,7 @@ "additives_tags" : [], "allergens" : "", "allergens_from_ingredients" : "", - "allergens_from_user" : "(es) ", + "allergens_from_user" : "(en) ", "allergens_hierarchy" : [], "allergens_tags" : [], "amino_acids_tags" : [], @@ -2462,7 +2566,7 @@ "2xxxxxxxxxxx" ], "complete" : 0, - "completeness" : 0.4, + "completeness" : "0.5", "correctors_tags" : [], "created_t" : "--ignore--", "creator" : "tests", @@ -2483,15 +2587,11 @@ "en:food-groups-1-known", "en:food-groups-2-known", "en:food-groups-3-unknown", - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" ], "data_quality_warnings_tags" : [ - "en:ingredients-unknown-score-above-0", - "en:ingredients-100-percent-unknown", "en:ecoscore-origins-of-ingredients-origins-are-100-percent-unknown", "en:ecoscore-packaging-packaging-data-missing", "en:ecoscore-production-system-no-label" @@ -2726,22 +2826,22 @@ }, "agribalyse" : { "agribalyse_proxy_food_code" : "32135", - "co2_agriculture" : 2.2396004, + "co2_agriculture" : "2.2396004", "co2_consumption" : 0, - "co2_distribution" : 0.019530673, - "co2_packaging" : 0.28159592, - "co2_processing" : 0.77051126, - "co2_total" : 3.564111983, - "co2_transportation" : 0.25287373, + "co2_distribution" : "0.019530673", + "co2_packaging" : "0.28159592", + "co2_processing" : "0.77051126", + "co2_total" : "3.564111983", + "co2_transportation" : "0.25287373", "code" : "32135", "dqr" : "4.03", - "ef_agriculture" : 0.50064279, + "ef_agriculture" : "0.50064279", "ef_consumption" : 0, - "ef_distribution" : 0.0048315303, - "ef_packaging" : 0.023715692, - "ef_processing" : 0.078716079, - "ef_total" : 0.6323498093, - "ef_transportation" : 0.024443718, + "ef_distribution" : "0.0048315303", + "ef_packaging" : "0.023715692", + "ef_processing" : "0.078716079", + "ef_total" : "0.6323498093", + "ef_transportation" : "0.024443718", "is_beverage" : 0, "name_en" : "Breakfast cereals, mix of puffed or extruded cereals, fortified with vitamins and chemical elements", "name_fr" : "Multi-céréales soufflées ou extrudées, enrichies en vitamines et minéraux", @@ -2911,64 +3011,61 @@ ], "ingredients" : [ { - "id" : "es:apple", + "ciqual_food_code" : "13050", + "id" : "en:apple", "percent_estimate" : 75, "percent_max" : 100, "percent_min" : 50, "rank" : 1, - "text" : "apple" + "text" : "apple", + "vegan" : "yes", + "vegetarian" : "yes" }, { - "id" : "es:water", + "ciqual_food_code" : "18066", + "id" : "en:water", "percent_estimate" : 25, "percent_max" : 50, "percent_min" : 0, "rank" : 2, - "text" : "water" + "text" : "water", + "vegan" : "yes", + "vegetarian" : "yes" } ], - "ingredients_analysis" : { - "en:palm-oil-content-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegan-status-unknown" : [ - "es:apple", - "es:water" - ], - "en:vegetarian-status-unknown" : [ - "es:apple", - "es:water" - ] - }, + "ingredients_analysis" : {}, "ingredients_analysis_tags" : [ - "en:palm-oil-content-unknown", - "en:vegan-status-unknown", - "en:vegetarian-status-unknown" + "en:palm-oil-free", + "en:vegan", + "en:vegetarian" ], "ingredients_from_or_that_may_be_from_palm_oil_n" : 0, "ingredients_from_palm_oil_n" : 0, "ingredients_from_palm_oil_tags" : [], "ingredients_hierarchy" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], + "ingredients_lc" : "en", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", "1-10" ], "ingredients_original_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:water" ], "ingredients_percent_analysis" : 1, "ingredients_tags" : [ - "es:apple", - "es:water" + "en:apple", + "en:fruit", + "en:water" ], "ingredients_text" : "apple, water", "ingredients_text_en" : "apple, water", + "ingredients_text_with_allergens" : "apple, water", "ingredients_text_with_allergens_en" : "apple, water", "ingredients_that_may_be_from_palm_oil_n" : 0, "ingredients_that_may_be_from_palm_oil_tags" : [], @@ -2976,14 +3073,11 @@ "ingredients_with_specified_percent_sum" : 0, "ingredients_with_unspecified_percent_n" : 2, "ingredients_with_unspecified_percent_sum" : 100, - "ingredients_without_ciqual_codes" : [ - "es:apple", - "es:water" - ], - "ingredients_without_ciqual_codes_n" : 2, + "ingredients_without_ciqual_codes" : [], + "ingredients_without_ciqual_codes_n" : 0, "interface_version_created" : "20150316.jqm2", "interface_version_modified" : "20150316.jqm2", - "known_ingredients_n" : 0, + "known_ingredients_n" : 3, "lang" : "es", "languages" : { "en:english" : 5 @@ -3007,7 +3101,6 @@ "main_countries_tags" : [], "minerals_tags" : [], "misc_tags" : [ - "en:nutriscore-not-computed", "en:nutrition-not-enough-data-to-compute-nutrition-score", "en:nutriscore-missing-nutrition-data", "en:nutriscore-missing-nutrition-data-energy", @@ -3017,6 +3110,10 @@ "en:nutriscore-missing-nutrition-data-sodium", "en:nutriscore-missing-nutrition-data-proteins", "en:nutrition-no-fiber", + "en:nutriscore-using-estimated-nutrition-facts", + "en:nutrition-fruits-vegetables-nuts-estimate-from-ingredients", + "en:nutrition-all-nutriscore-values-known", + "en:nutriscore-computed", "en:packagings-number-of-components-0", "en:packagings-not-complete", "en:packagings-empty", @@ -3031,26 +3128,121 @@ "en:ecoscore-grade-changed", "en:main-countries-new-product" ], - "nova_group_debug" : "no nova group if too many ingredients are unknown: 2 out of 2", - "nova_group_error" : "too_many_unknown_ingredients", + "nova_group" : 1, + "nova_group_debug" : "", + "nova_groups" : "1", + "nova_groups_markers" : {}, "nova_groups_tags" : [ - "unknown" + "en:1-unprocessed-or-minimally-processed-foods" ], "nucleotides_tags" : [], "nutrient_levels" : {}, "nutrient_levels_tags" : [], "nutriments" : { - "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 0, - "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 0 + "fruits-vegetables-nuts-estimate-from-ingredients_100g" : 50, + "fruits-vegetables-nuts-estimate-from-ingredients_serving" : 50, + "nova-group" : 1, + "nova-group_100g" : 1, + "nova-group_serving" : 1, + "nutrition-score-fr" : -1, + "nutrition-score-fr_100g" : -1 + }, + "nutriments_estimated" : { + "alcohol_100g" : 0, + "beta-carotene_100g" : "1.275e-05", + "calcium_100g" : "0.0055325", + "carbohydrates_100g" : "8.025", + "cholesterol_100g" : 0, + "copper_100g" : "2.75e-05", + "energy-kcal_100g" : "36.675", + "energy-kj_100g" : "155.25", + "energy_100g" : "155.25", + "fat_100g" : "0.0975", + "fiber_100g" : "0.975", + "fructose_100g" : "4.5225", + "galactose_100g" : 0, + "glucose_100g" : "2.4375", + "iodine_100g" : "7.5e-08", + "iron_100g" : "6e-05", + "lactose_100g" : 0, + "magnesium_100g" : "0.0032475", + "maltose_100g" : 0, + "manganese_100g" : "2.8705e-05", + "pantothenic-acid_100g" : "5.325e-05", + "phosphorus_100g" : "0.00825", + "phylloquinone_100g" : "4.5e-07", + "polyols_100g" : "0.4425", + "potassium_100g" : "0.0676825", + "proteins_100g" : "0.2025", + "salt_100g" : "0.0019", + "saturated-fat_100g" : "0.01575", + "selenium_100g" : "2.375e-07", + "sodium_100g" : "0.0006", + "starch_100g" : 0, + "sucrose_100g" : "0.615", + "sugars_100g" : "7.575", + "vitamin-a_100g" : 0, + "vitamin-b12_100g" : 0, + "vitamin-b1_100g" : "1.425e-05", + "vitamin-b2_100g" : "2.1e-05", + "vitamin-b6_100g" : "2.775e-05", + "vitamin-b9_100g" : 0, + "vitamin-c_100g" : "0.003", + "vitamin-d_100g" : 0, + "vitamin-e_100g" : "3.75e-05", + "vitamin-pp_100g" : "6.825e-05", + "water_100g" : "90.025", + "zinc_100g" : "4.025e-05" }, + "nutriscore_data" : { + "energy" : "155.25", + "energy_points" : 0, + "energy_value" : "155.3", + "fiber" : "0.975", + "fiber_points" : 1, + "fiber_value" : "0.98", + "fruits_vegetables_nuts_colza_walnut_olive_oils" : 50, + "fruits_vegetables_nuts_colza_walnut_olive_oils_points" : 1, + "fruits_vegetables_nuts_colza_walnut_olive_oils_value" : 50, + "grade" : "a", + "is_beverage" : 0, + "is_cheese" : 0, + "is_fat" : 0, + "is_water" : 0, + "negative_points" : 1, + "positive_points" : 2, + "proteins" : "0.2025", + "proteins_points" : 0, + "proteins_value" : "0.2", + "saturated_fat" : "0.01575", + "saturated_fat_points" : 0, + "saturated_fat_ratio" : "16.1538461538462", + "saturated_fat_ratio_points" : 2, + "saturated_fat_ratio_value" : "16.2", + "saturated_fat_value" : 0, + "score" : -1, + "sodium" : "0.6", + "sodium_points" : 0, + "sodium_value" : "0.6", + "sugars" : "7.575", + "sugars_points" : 1, + "sugars_value" : "7.58" + }, + "nutriscore_grade" : "a", + "nutriscore_score" : -1, + "nutriscore_score_opposite" : 1, "nutrition_data_per" : "100g", "nutrition_data_prepared_per" : "100g", + "nutrition_grade_fr" : "a", + "nutrition_grades" : "a", "nutrition_grades_tags" : [ - "unknown" + "a" ], "nutrition_score_beverage" : 0, "nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins", - "nutrition_score_warning_no_fiber" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1, + "nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 50, + "nutrition_score_warning_nutriments_estimated" : 1, "origin" : "China", "origin_en" : "China", "other_nutritional_substances_tags" : [], @@ -3081,10 +3273,10 @@ "rev" : 1, "serving_quantity" : 10, "serving_size" : "10 g", - "states" : "en:to-be-completed, en:nutrition-facts-to-be-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", + "states" : "en:to-be-completed, en:nutrition-facts-completed, en:ingredients-completed, en:expiration-date-to-be-completed, en:packaging-code-to-be-completed, en:characteristics-to-be-completed, en:origins-to-be-completed, en:categories-completed, en:brands-to-be-completed, en:packaging-to-be-completed, en:quantity-completed, en:product-name-completed, en:photos-to-be-uploaded", "states_hierarchy" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -3099,7 +3291,7 @@ ], "states_tags" : [ "en:to-be-completed", - "en:nutrition-facts-to-be-completed", + "en:nutrition-facts-completed", "en:ingredients-completed", "en:expiration-date-to-be-completed", "en:packaging-code-to-be-completed", @@ -3114,10 +3306,10 @@ ], "traces" : "", "traces_from_ingredients" : "", - "traces_from_user" : "(es) ", + "traces_from_user" : "(en) ", "traces_hierarchy" : [], "traces_tags" : [], - "unknown_ingredients_n" : 2, + "unknown_ingredients_n" : 0, "unknown_nutrients_tags" : [], "url" : "http://world.openfoodfacts.localhost/product/200000000045/vegan-test-snack", "vitamins_tags" : [], diff --git a/tests/unit/expected_test_results/attributes/en-attributes.json b/tests/unit/expected_test_results/attributes/en-attributes.json index da3e95bb506d5..e0d44bd73b4fb 100644 --- a/tests/unit/expected_test_results/attributes/en-attributes.json +++ b/tests/unit/expected_test_results/attributes/en-attributes.json @@ -1003,6 +1003,7 @@ "en:e102", "en:e120" ], + "ingredients_lc" : "en", "ingredients_n" : 11, "ingredients_n_tags" : [ "11", diff --git a/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json b/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json index ccb4a2a8873fa..35222e2c6d810 100644 --- a/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json +++ b/tests/unit/expected_test_results/attributes/en-ecoscore-score-at-20-threshold.json @@ -780,6 +780,7 @@ ], "food_groups_tags" : [], "ingredients_from_palm_oil_tags" : [], + "ingredients_lc" : "en", "ingredients_text" : "", "ingredients_that_may_be_from_palm_oil_tags" : [], "languages" : {}, diff --git a/tests/unit/expected_test_results/attributes/en-maybe-vegan.json b/tests/unit/expected_test_results/attributes/en-maybe-vegan.json index 75f98f76d13ac..835c3e332a02b 100644 --- a/tests/unit/expected_test_results/attributes/en-maybe-vegan.json +++ b/tests/unit/expected_test_results/attributes/en-maybe-vegan.json @@ -681,6 +681,7 @@ "en:palm-oil-and-fat", "en:enzyme" ], + "ingredients_lc" : "en", "ingredients_n" : 3, "ingredients_n_tags" : [ "3", diff --git a/tests/unit/expected_test_results/attributes/en-no-ingredients.json b/tests/unit/expected_test_results/attributes/en-no-ingredients.json index f100a71e0d0b5..6b19457b67de2 100644 --- a/tests/unit/expected_test_results/attributes/en-no-ingredients.json +++ b/tests/unit/expected_test_results/attributes/en-no-ingredients.json @@ -779,6 +779,7 @@ "en:milk-and-dairy-products", "en:cheese" ], + "ingredients_lc" : "en", "languages" : {}, "languages_codes" : {}, "languages_hierarchy" : [], diff --git a/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json b/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json index ef218a35a64a8..4670c4d8a948d 100644 --- a/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json +++ b/tests/unit/expected_test_results/attributes/en-nova-groups-markers.json @@ -896,6 +896,7 @@ "en:corn-syrup", "en:glucose-fructose-syrup" ], + "ingredients_lc" : "en", "ingredients_n" : 7, "ingredients_n_tags" : [ "7", diff --git a/tests/unit/expected_test_results/attributes/en-nutriscore.json b/tests/unit/expected_test_results/attributes/en-nutriscore.json index 8d1b27cf0369c..50520c5a298f2 100644 --- a/tests/unit/expected_test_results/attributes/en-nutriscore.json +++ b/tests/unit/expected_test_results/attributes/en-nutriscore.json @@ -808,6 +808,7 @@ "ingredients_hierarchy" : [ "en:fruit" ], + "ingredients_lc" : "en", "ingredients_n" : 1, "ingredients_n_tags" : [ "1", diff --git a/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json b/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json index d41e88cc1e696..de259f6460b6e 100644 --- a/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json +++ b/tests/unit/expected_test_results/attributes/en-unknown-ingredients.json @@ -816,6 +816,7 @@ "ingredients_hierarchy" : [ "en:some-ingredient-that-we-do-not-recognize" ], + "ingredients_lc" : "en", "ingredients_n" : 1, "ingredients_n_tags" : [ "1", diff --git a/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json b/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json index 640a6985161a6..ee910e592d0ee 100644 --- a/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json +++ b/tests/unit/expected_test_results/attributes/fr-palm-kernel-fat.json @@ -653,6 +653,7 @@ "en:vegetable-oil-and-fat", "en:palm-kernel-oil-and-fat" ], + "ingredients_lc" : "fr", "ingredients_n" : 1, "ingredients_n_tags" : [ "1", diff --git a/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json b/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json index bf0398c4fa998..809835c9ed18c 100644 --- a/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json +++ b/tests/unit/expected_test_results/attributes/fr-palm-oil-free.json @@ -675,6 +675,7 @@ "en:disaccharide", "en:chocolate" ], + "ingredients_lc" : "fr", "ingredients_n" : 4, "ingredients_n_tags" : [ "4", diff --git a/tests/unit/expected_test_results/attributes/fr-palm-oil.json b/tests/unit/expected_test_results/attributes/fr-palm-oil.json index a1ded8fa866d1..90b22d830ead9 100644 --- a/tests/unit/expected_test_results/attributes/fr-palm-oil.json +++ b/tests/unit/expected_test_results/attributes/fr-palm-oil.json @@ -665,6 +665,7 @@ "en:vegetable-oil-and-fat", "en:palm-oil-and-fat" ], + "ingredients_lc" : "fr", "ingredients_n" : 2, "ingredients_n_tags" : [ "2", diff --git a/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json b/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json index 6cac49caeccf3..17c4b1c6cf55f 100644 --- a/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json +++ b/tests/unit/expected_test_results/attributes/fr-vegetable-oils.json @@ -670,6 +670,7 @@ "en:vegetable-oil-and-fat", "en:salt" ], + "ingredients_lc" : "fr", "ingredients_n" : 3, "ingredients_n_tags" : [ "3",