Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: food contact packagings for chocolate bars #11343

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions lib/ProductOpener/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ if (not defined $flavor) {
die("The PRODUCT_OPENER_FLAVOR_SHORT environment variable must be set.");
}

# %options will be redefined by autoload below
# but we need it to avoid Perl complaining
%ProductOpener::Config:: % options = ();

use Module::Load;

autoload("ProductOpener::Config_$flavor");
Expand Down
6 changes: 2 additions & 4 deletions lib/ProductOpener/Display.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8004,12 +8004,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
Loading