diff --git a/lib/ProductOpener/Config_off.pm b/lib/ProductOpener/Config_off.pm index a393db09a760d..50f5e5c5eff10 100644 --- a/lib/ProductOpener/Config_off.pm +++ b/lib/ProductOpener/Config_off.pm @@ -613,7 +613,6 @@ $options{categories_exempted_from_nutriscore} = [ en:spices en:sugar-substitutes en:vinegars - en:pet-food en:non-food-products ) ]; diff --git a/lib/ProductOpener/Products.pm b/lib/ProductOpener/Products.pm index 5044332652e5f..da0d514cd7df6 100644 --- a/lib/ProductOpener/Products.pm +++ b/lib/ProductOpener/Products.pm @@ -95,6 +95,7 @@ BEGIN { &compute_completeness_and_missing_tags &compute_product_history_and_completeness &compute_languages + &review_product_type &compute_changes_diff_text &compute_data_sources &compute_sort_keys @@ -3000,6 +3001,48 @@ sub compute_languages ($product_ref) { return; } +=head2 review_product_type ( $product_ref ) + +Reviews the product type based on the presence of specific tags in the categories field. +Updates the product type if necessary. + +=head3 Arguments + +=head4 Product reference $product_ref + +A reference to a hash containing the product details. + +=cut + +sub review_product_type ($product_ref) { + + my $error; + + my $expected_type; + if (has_tag($product_ref, "categories", "en:open-beauty-facts")) { + $expected_type = "beauty"; + } + elsif (has_tag($product_ref, "categories", "en:open-food-facts")) { + $expected_type = "food"; + } + elsif (has_tag($product_ref, "categories", "en:open-pet-food-facts")) { + $expected_type = "petfood"; + } + elsif (has_tag($product_ref, "categories", "en:open-products-facts")) { + $expected_type = "product"; + } + + if ($expected_type and ($product_ref->{product_type} ne $expected_type)) { + $error = change_product_type($product_ref, $expected_type); + } + + if ($error) { + $log->error("review_product_type - error", {error => $error, product_ref => $product_ref}); + } + + return; +} + =head2 process_product_edit_rules ($product_ref) Process the edit_rules (see C<@edit_rules> in in Config file). @@ -3723,6 +3766,11 @@ sub analyze_and_enrich_product_data ($product_ref, $response_ref) { compute_languages($product_ref); # need languages for allergens detection and cleaning ingredients + # change the product type of non-food categorized products (issue #11094) + if (has_tag($product_ref, "categories", "en:incorrect-product-type")) { + review_product_type($product_ref); + } + # Run special analysis, score calculations that it specific to the product type if (($options{product_type} eq "food")) { diff --git a/scripts/update_all_products.pl b/scripts/update_all_products.pl index 6a1a1fe167a70..75e2a620f592a 100755 --- a/scripts/update_all_products.pl +++ b/scripts/update_all_products.pl @@ -1381,6 +1381,10 @@ assign_ciqual_codes($product_ref); } + if (has_tag($product_ref, "categories", "en:incorrect-product-type")) { + $product_values_changed = 1; + } + my $any_change = $product_values_changed; if (not $pretend) { if (!$any_change) { diff --git a/taxonomies/beauty/categories.txt b/taxonomies/beauty/categories.txt index 1f215a51b4837..d541f7aed9cd9 100644 --- a/taxonomies/beauty/categories.txt +++ b/taxonomies/beauty/categories.txt @@ -1,810 +1,844 @@ -stopwords:fr:aux,au,de,le,du,la,a,et,avec,pour - -synonyms:en:flavoured,flavored +stopwords:fr: aux, au, de, le, du, la, a, et, avec, pour + +synonyms:en: flavoured, flavored + +en: Incorrect product type +bg: Неправилен product type +ca: Tipus de producte incorrecte +de: Falscher product type +es: Tipo de producto incorrecto +fi: Väärä product type +fr: Mauvais product type +hr: Pogrešan product type +it: Tipo di prodotto errato +nl: Verkeerd product type +pt: Tipo de produto incorreto +ru: Неправильный product type + +< en: Incorrect product type +en: Non beauty products +bg: Некозметични продукти +ca: Productes no de bellesa +de: Non-Beauty-Produkte, Non Beauty Produkte +es: Productos no de belleza +fi: ei kauneustuote +fr: Non beauté +hr: Neprehrambeni proizvodi za ljepotu +it: Prodotti non di bellezza +nl: Non-beauty +pt: Produtos não de beleza +ru: Непродукты для красоты, Не косметические продукты + +< en:Non beauty products +en: Open Food Facts, OFF +xx: Open Food Facts, OFF + +< en:Non beauty products +en: Open Pet Food Facts, OFF +xx: Open Pet Food Facts, OFF + +< en:Non beauty products +en: Open Products Facts, OPF +xx: Open Products Facts, OPF ###### CATEGORIE HYGIENE -en:Hygiene -fr:Hygiène -nl:Hygiëne +en: Hygiene +fr: Hygiène +nl: Hygiëne - ['en:incorrect-product-type', 'en:non-food-products', 'en:open-pet-food-facts'], + product_type => 'food' +}; +review_product_type($product_ref); +is($product_ref->{product_type}, 'petfood') || diag Dumper $product_ref; +# beauty to product +$product_ref = { + categories_tags => ['en:incorrect-product-type', 'en:non-beauty-products', 'en:open-products-facts'], + product_type => 'beauty' +}; +review_product_type($product_ref); +is($product_ref->{product_type}, 'product') || diag Dumper $product_ref; +# food to beauty AND product -> move to beauty (handled by alphabetical order) +$product_ref = { + categories_tags => + ['en:incorrect-product-type', 'en:non-food-products', 'en:open-beauty-facts', 'en:open-products-facts'], + product_type => 'food' +}; +review_product_type($product_ref); +is($product_ref->{product_type}, 'beauty') || diag Dumper $product_ref; +# rerun same test based on result of previous test, +# will remain beauty because has tag beauty is evaluated first +# and tag remains after migration +review_product_type($product_ref); +is($product_ref->{product_type}, 'beauty') || diag Dumper $product_ref; + done_testing();