Skip to content

Commit

Permalink
fix: food contact packagings for chocolate bars (#11343)
Browse files Browse the repository at this point in the history
Some fixes + support for chocolate bars
  • Loading branch information
stephanegigandet authored Feb 12, 2025
1 parent f101551 commit c485494
Show file tree
Hide file tree
Showing 100 changed files with 592 additions and 49 deletions.
6 changes: 2 additions & 4 deletions lib/ProductOpener/Display.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8012,12 +8012,10 @@ JS
$product_ref->{environmental_score_data});
}

# 2025/01 - For moderators, determine which packaging components are in contact with food, so that we can display them
# 2025/02 - Determine which packaging components are in contact with food, so that we can display them
# This is for initial development of the feature, once finalized, we could compute and store this data in the product

if ($User{moderator}) {
ProductOpener::PackagingFoodContact::determine_food_contact_of_packaging_components_service($product_ref);
}
ProductOpener::PackagingFoodContact::determine_food_contact_of_packaging_components_service($product_ref);

# Activate knowledge panels for all users

Expand Down
4 changes: 4 additions & 0 deletions lib/ProductOpener/FoodProducts.pm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ use ProductOpener::FoodGroups qw/compute_food_groups/;
use ProductOpener::Nutriscore qw/:all/;
use ProductOpener::EnvironmentalScore qw/compute_environmental_score/;
use ProductOpener::ForestFootprint qw/compute_forest_footprint/;
use ProductOpener::PackagingFoodContact qw/determine_food_contact_of_packaging_components_service/;

use Log::Any qw($log);

Expand Down Expand Up @@ -112,6 +113,9 @@ sub specific_processes_for_food_product ($product_ref) {
compute_environmental_score($product_ref);
compute_forest_footprint($product_ref);

# Determine packaging components in contact with food
determine_food_contact_of_packaging_components_service($product_ref);

return;
}

Expand Down
44 changes: 39 additions & 5 deletions lib/ProductOpener/PackagingFoodContact.pm
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ sub determine_food_contact_of_packaging_components_service (
# indicate that the service is updating the "packagings" structure
$updated_product_fields_ref->{packagings} = 1;

determine_food_contact_of_packaging_components($packagings_ref);
determine_food_contact_of_packaging_components($packagings_ref, $product_ref);

return;
}
Expand Down Expand Up @@ -156,7 +156,7 @@ sub get_matching_and_non_matching_packaging_components ($packagings_ref, $condit
my $matched_value = 0;

foreach my $value (@values) {
if (is_a($packaging_taxonomies{$property}, $value, $packaging_ref->{$property})) {
if (is_a($packaging_taxonomies{$property}, $packaging_ref->{$property}, $value)) {
$matched_value = 1;
last;
}
Expand Down Expand Up @@ -193,17 +193,21 @@ sub set_food_contact_property_of_packaging_components ($packagings_ref, $food_co
return;
}

=head2 determine_food_contact_of_packaging_components ($packagings_ref)
=head2 determine_food_contact_of_packaging_components ($packagings_ref, $product_ref = {})
Determine if packaging components are in contact with the food.
=head3 Parameters
=head4 $packagings_ref packaging data
=head4 $product_ref product data (optional)
Used to apply specific rules (e.g. for products in specific categories)
=cut

sub determine_food_contact_of_packaging_components ($packagings_ref) {
sub determine_food_contact_of_packaging_components ($packagings_ref, $product_ref = {}) {

# Cans: only the can itself is in contact with the food
my ($cans_ref, $non_cans_ref)
Expand Down Expand Up @@ -231,7 +235,7 @@ sub determine_food_contact_of_packaging_components ($packagings_ref) {
# Otherwise, if there is a lid or a cap, it is in contact wit the food
else {
my ($lids_ref, $non_lids_ref)
= get_matching_and_non_matching_packaging_components($non_bottles_ref, {shape => ["en:lid", "en:cap"]});
= get_matching_and_non_matching_packaging_components($non_bottles_ref, {shape => ["en:lid-or-cap"]});
if (@$lids_ref) {
set_food_contact_property_of_packaging_components($lids_ref, 1);
}
Expand Down Expand Up @@ -264,6 +268,36 @@ sub determine_food_contact_of_packaging_components ($packagings_ref) {
return;
}

# Specific rules for chocolate bars
if (has_tag($product_ref, "categories", "en:chocolates")) {

# We could have a plastic wrap in contact with the chocolate, or as an outside packaging if there are several paper bars..

# If there is a metallic film, sheet, wrap etc., it is in contact with the food
my ($metals_ref, $non_metals_ref)
= get_matching_and_non_matching_packaging_components($packagings_ref,
{material => "en:metal", shape => ["en:film", "en:sheet"]});
if (@$metals_ref) {
set_food_contact_property_of_packaging_components($metals_ref, 1);
return;
}

# Otherwise, if there is a plastic film, sheet, wrap etc. , it is in contact with the food
my ($plastics_ref, $non_plastics_ref)
= get_matching_and_non_matching_packaging_components($packagings_ref,
{material => "en:plastic", shape => ["en:film", "en:sheet"]});
if (@$plastics_ref) {
set_food_contact_property_of_packaging_components($plastics_ref, 1);
return;
}
}

# If there is only one packaging component, it is in contact with the food
if (@$packagings_ref == 1) {
set_food_contact_property_of_packaging_components($packagings_ref, 1);
return;
}

return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1188,12 +1188,14 @@
"packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard",
"packagings" : [
{
"food_contact" : 0,
"material" : "en:wood",
"number_of_units" : 1,
"recycling" : "en:recycle",
"shape" : "en:box"
},
{
"food_contact" : 1,
"material" : "en:glass",
"number_of_units" : 6,
"quantity_per_unit" : "25cl",
Expand All @@ -1203,12 +1205,14 @@
"shape" : "en:bottle"
},
{
"food_contact" : 1,
"material" : "en:steel",
"number_of_units" : 3,
"recycling" : "en:recycle",
"shape" : "en:lid"
},
{
"food_contact" : 0,
"material" : "en:plastic",
"number_of_units" : 1,
"recycling" : "en:discard",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2596,7 +2596,7 @@
"element_type" : "text",
"text_element" : {
"evaluation" : "good",
"html" : "\n \n \n 1 x \n <strong>\n Box\n \n </strong>\n \n (Wood)\n \n \n <br>\n \n \n \n \n \n 3 x \n <strong>\n Lid\n \n </strong>\n \n (Steel)\n \n \n <br>\n \n \n \n \n ",
"html" : "\n \n \n 1 x \n <strong>\n Box\n \n </strong>\n \n (Wood)\n \n \n <br>\n \n \n \n \n \n 3 x \n <strong>\n Lid\n \n </strong>\n \n (Steel)\n \n \n - In contact with food\n \n <br>\n \n \n \n \n ",
"icon_alt" : "Recycle",
"icon_color_from_evaluation" : true,
"icon_url" : "http://static.openfoodfacts.localhost/images/icons/dist/recycle-variant.svg",
Expand All @@ -2618,7 +2618,7 @@
"element_type" : "text",
"text_element" : {
"evaluation" : "neutral",
"html" : "\n \n \n \n \n 6 x \n <strong>\n Bottle\n 25cl \n </strong>\n \n (Glass)\n \n \n <br>\n \n \n \n \n \n \n ",
"html" : "\n \n \n \n \n 6 x \n <strong>\n Bottle\n 25cl \n </strong>\n \n (Glass)\n \n \n - In contact with food\n \n <br>\n \n \n \n \n \n \n ",
"icon_alt" : "Unknown",
"icon_color_from_evaluation" : true,
"icon_url" : "http://static.openfoodfacts.localhost/images/icons/dist/help.svg",
Expand Down Expand Up @@ -3279,12 +3279,14 @@
"packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard",
"packagings" : [
{
"food_contact" : 0,
"material" : "en:wood",
"number_of_units" : "1",
"recycling" : "en:recycle",
"shape" : "en:box"
},
{
"food_contact" : 1,
"material" : "en:glass",
"number_of_units" : "6",
"quantity_per_unit" : "25cl",
Expand All @@ -3294,12 +3296,14 @@
"shape" : "en:bottle"
},
{
"food_contact" : 1,
"material" : "en:steel",
"number_of_units" : "3",
"recycling" : "en:recycle",
"shape" : "en:lid"
},
{
"food_contact" : 0,
"material" : "en:plastic",
"number_of_units" : "1",
"recycling" : "en:discard",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1188,12 +1188,14 @@
"packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard",
"packagings" : [
{
"food_contact" : 0,
"material" : "en:wood",
"number_of_units" : 1,
"recycling" : "en:recycle",
"shape" : "en:box"
},
{
"food_contact" : 1,
"material" : "en:glass",
"number_of_units" : 6,
"quantity_per_unit" : "25cl",
Expand All @@ -1203,12 +1205,14 @@
"shape" : "en:bottle"
},
{
"food_contact" : 1,
"material" : "en:steel",
"number_of_units" : 3,
"recycling" : "en:recycle",
"shape" : "en:lid"
},
{
"food_contact" : 0,
"material" : "en:plastic",
"number_of_units" : 1,
"recycling" : "en:discard",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3250,7 +3250,7 @@
"element_type" : "text",
"text_element" : {
"evaluation" : "good",
"html" : "\n \n \n 1 x \n <strong>\n Box\n \n </strong>\n \n (Wood)\n \n \n <br>\n \n \n \n \n \n 3 x \n <strong>\n Lid\n \n </strong>\n \n (Steel)\n \n \n <br>\n \n \n \n \n ",
"html" : "\n \n \n 1 x \n <strong>\n Box\n \n </strong>\n \n (Wood)\n \n \n <br>\n \n \n \n \n \n 3 x \n <strong>\n Lid\n \n </strong>\n \n (Steel)\n \n \n - In contact with food\n \n <br>\n \n \n \n \n ",
"icon_alt" : "Recycle",
"icon_color_from_evaluation" : true,
"icon_url" : "http://static.openfoodfacts.localhost/images/icons/dist/recycle-variant.svg",
Expand All @@ -3272,7 +3272,7 @@
"element_type" : "text",
"text_element" : {
"evaluation" : "neutral",
"html" : "\n \n \n \n \n 6 x \n <strong>\n Bottle\n 25cl \n </strong>\n \n (Glass)\n \n \n <br>\n \n \n \n \n \n \n ",
"html" : "\n \n \n \n \n 6 x \n <strong>\n Bottle\n 25cl \n </strong>\n \n (Glass)\n \n \n - In contact with food\n \n <br>\n \n \n \n \n \n \n ",
"icon_alt" : "Unknown",
"icon_color_from_evaluation" : true,
"icon_url" : "http://static.openfoodfacts.localhost/images/icons/dist/help.svg",
Expand Down Expand Up @@ -3933,12 +3933,14 @@
"packaging_text_en" : "1 wooden box to recycle, 6 25cl glass bottles to reuse, 3 steel lids to recycle, 1 plastic film to discard",
"packagings" : [
{
"food_contact" : 0,
"material" : "en:wood",
"number_of_units" : "1",
"recycling" : "en:recycle",
"shape" : "en:box"
},
{
"food_contact" : 1,
"material" : "en:glass",
"number_of_units" : "6",
"quantity_per_unit" : "25cl",
Expand All @@ -3948,12 +3950,14 @@
"shape" : "en:bottle"
},
{
"food_contact" : 1,
"material" : "en:steel",
"number_of_units" : "3",
"recycling" : "en:recycle",
"shape" : "en:lid"
},
{
"food_contact" : 0,
"material" : "en:plastic",
"number_of_units" : "1",
"recycling" : "en:discard",
Expand Down
Loading

0 comments on commit c485494

Please sign in to comment.