Skip to content

Commit

Permalink
Ecoscore: change structure of country specific ecoscore_data and comp…
Browse files Browse the repository at this point in the history
…ute Eco-Score for 50 more countries (#6030)

* updated distances data with more countries

* better structure fo country specific ecoscore data

* update attributes to use new ecoscore structure

* update tests

* enable Eco-Score for all countries for which we have transportation data
  • Loading branch information
stephanegigandet authored Oct 29, 2021
1 parent ba8c5b6 commit 22dccb8
Show file tree
Hide file tree
Showing 49 changed files with 14,199 additions and 2,520 deletions.
504 changes: 255 additions & 249 deletions ecoscore/data/distances.csv

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions lib/ProductOpener/Attributes.pm
Original file line number Diff line number Diff line change
Expand Up @@ -600,12 +600,12 @@ sub compute_attribute_ecoscore($$$) {
if ((defined $product_ref->{ecoscore_data}) and ($product_ref->{ecoscore_data}{status} eq "known")) {
$attribute_ref->{status} = "known";

my $score = $product_ref->{ecoscore_data}{score};
my $grade = $product_ref->{ecoscore_data}{grade};
my $score = $product_ref->{ecoscore_score} // 0;
my $grade = $product_ref->{ecoscore_grade};

if (defined $product_ref->{ecoscore_data}{"score_" . $cc}) {
$score = $product_ref->{ecoscore_data}{"score_" . $cc};
$grade = $product_ref->{ecoscore_data}{"grade_" . $cc};
if ((defined $product_ref->{ecoscore_data}{"scores"}) and (defined $product_ref->{ecoscore_data}{"scores"}{$cc})) {
$score = $product_ref->{ecoscore_data}{"scores"}{$cc} // 0;
$grade = $product_ref->{ecoscore_data}{"grades"}{$cc};
}

$log->debug("compute ecoscore attribute - known", { code => $product_ref->{code}, score => $score, grade => $grade }) if $log->is_debug();
Expand Down
103 changes: 56 additions & 47 deletions lib/ProductOpener/Ecoscore.pm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ List of countries for which we are going to compute and display the Eco-Score.
The list is different from %ecoscore_countries that can contain more countries for which we have some
data to compute the Eco-Score (e.g. distances).
2021-10-28: we will now enable Eco-Score for all available countries,
so this list will be overriden when we load the Eco-Score data.
=cut

@ecoscore_countries_enabled_sorted = qw(be ch de es fr ie it lu nl uk);
Expand Down Expand Up @@ -202,6 +205,9 @@ sub load_ecoscore_data_origins_of_ingredients_distances() {
}
@ecoscore_countries_sorted = sort keys %ecoscore_countries;

%ecoscore_countries_enabled = %ecoscore_countries;
@ecoscore_countries_enabled_sorted = @ecoscore_countries_sorted;

$ecoscore_data{origins}{"en:world"} = $ecoscore_data{origins}{"en:unknown"};
$ecoscore_data{origins}{"en:european-union-and-non-european-union"} = $ecoscore_data{origins}{"en:unknown"};

Expand Down Expand Up @@ -645,16 +651,14 @@ sub compute_ecoscore($) {
$product_ref->{ecoscore_data}{status} = "known";

my $missing_data_warning;

$product_ref->{ecoscore_data}{scores} = {};
$product_ref->{ecoscore_data}{grades} = {};

# Compute the Eco-Score for all countries + a default Eco-Score without transportation bonus/malus
foreach my $cc (@ecoscore_countries_enabled_sorted, undef) {

my $suffix = "";
if (defined $cc) {
$suffix .= "_" . $cc;
}
# Compute the Eco-Score for all countries
foreach my $cc (@ecoscore_countries_enabled_sorted) {

$product_ref->{ecoscore_data}{"score" . $suffix} = $product_ref->{ecoscore_data}{agribalyse}{score};
$product_ref->{ecoscore_data}{"scores"}{$cc} = $product_ref->{ecoscore_data}{agribalyse}{score};

$log->debug("compute_ecoscore - agribalyse score", { cc => $cc, agribalyse_score => $product_ref->{ecoscore_data}{agribalyse}{score} }) if $log->is_debug();

Expand All @@ -664,15 +668,20 @@ sub compute_ecoscore($) {

foreach my $adjustment (keys %{$product_ref->{ecoscore_data}{adjustments}}) {

my $value = "value";
if ((defined $cc) and (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"value_" . $cc})) {
$value = "value_" . $cc;
my $value;
if ((defined $cc)
and (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"values"})
and (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"values"}{$cc})) {
$value = $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"values"}{$cc};
}
elsif (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"value"}) {
$value = $product_ref->{ecoscore_data}{adjustments}{$adjustment}{"value"};
}

if (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{$value}) {
$bonus += $product_ref->{ecoscore_data}{adjustments}{$adjustment}{$value};
if (defined $value) {
$bonus += $value;
$log->debug("compute_ecoscore - add adjustment", { adjustment => $adjustment,
$value => $product_ref->{ecoscore_data}{adjustments}{$adjustment}{$value} }) if $log->is_debug();
value => $value }) if $log->is_debug();
}
if (defined $product_ref->{ecoscore_data}{adjustments}{$adjustment}{warning}) {
$missing_data_warning = 1;
Expand All @@ -684,38 +693,38 @@ sub compute_ecoscore($) {
$bonus = 25;
}

$product_ref->{ecoscore_data}{"score" . $suffix} += $bonus;
$product_ref->{ecoscore_data}{"scores"}{$cc} += $bonus;

# Assign A to E grade

if ($product_ref->{ecoscore_data}{"score" . $suffix} >= 80) {
$product_ref->{ecoscore_data}{"grade" . $suffix} = "a";
if ($product_ref->{ecoscore_data}{"scores"}{$cc} >= 80) {
$product_ref->{ecoscore_data}{"grades"}{$cc} = "a";
}
elsif ($product_ref->{ecoscore_data}{"score" . $suffix} >= 60) {
$product_ref->{ecoscore_data}{"grade" . $suffix} = "b";
elsif ($product_ref->{ecoscore_data}{"scores"}{$cc} >= 60) {
$product_ref->{ecoscore_data}{"grades"}{$cc} = "b";
}
elsif ($product_ref->{ecoscore_data}{"score" . $suffix} >= 40) {
$product_ref->{ecoscore_data}{"grade" . $suffix} = "c";
elsif ($product_ref->{ecoscore_data}{"scores"}{$cc} >= 40) {
$product_ref->{ecoscore_data}{"grades"}{$cc} = "c";
}
elsif ($product_ref->{ecoscore_data}{"score" . $suffix} >= 20) {
$product_ref->{ecoscore_data}{"grade" . $suffix} = "d";
elsif ($product_ref->{ecoscore_data}{"scores"}{$cc} >= 20) {
$product_ref->{ecoscore_data}{"grades"}{$cc} = "d";
}
else {
$product_ref->{ecoscore_data}{"grade" . $suffix} = "e";
$product_ref->{ecoscore_data}{"grades"}{$cc} = "e";
}

# If a product has the grade A and it contains a non-biodegradable and non-recyclable material, downgrade to B
if (($product_ref->{ecoscore_data}{"grade" . $suffix} eq "a")
if (($product_ref->{ecoscore_data}{"grades"}{$cc} eq "a")
and ($product_ref->{ecoscore_data}{adjustments}{packaging}{non_recyclable_and_non_biodegradable_materials} > 0)) {

$product_ref->{"downgraded"} = "non_recyclable_and_non_biodegradable_materials";
$product_ref->{ecoscore_data}{"grade" . $suffix} = "b";
$product_ref->{ecoscore_data}{"score" . $suffix} = 79;
$product_ref->{ecoscore_data}{"grades"}{$cc} = "b";
$product_ref->{ecoscore_data}{"scores"}{$cc} = 79;
}

$log->debug("compute_ecoscore - final score and grade", { score => $product_ref->{"score" . $suffix}, grade => $product_ref->{"grade" . $suffix}}) if $log->is_debug();
$log->debug("compute_ecoscore - final score and grade", { score => $product_ref->{"scores"}{$cc}, grade => $product_ref->{"grades"}{$cc}}) if $log->is_debug();
}

# The following values correspond to the Eco-Score for France.
# at run-time, they may be changed to the values for a specific country
# after localize_ecoscore() is called
Expand All @@ -725,8 +734,10 @@ sub compute_ecoscore($) {
# Unfortunately there is a MongoDB index limit and we cannot create a different set of field
# for each country.

$product_ref->{"ecoscore_score"} = $product_ref->{ecoscore_data}{"score_fr"};
$product_ref->{"ecoscore_grade"} = $product_ref->{ecoscore_data}{"grade_fr"};
$product_ref->{ecoscore_data}{"score"} = $product_ref->{ecoscore_data}{"scores"}{"fr"};
$product_ref->{ecoscore_data}{"grade"} = $product_ref->{ecoscore_data}{"grades"}{"fr"};
$product_ref->{"ecoscore_score"} = $product_ref->{ecoscore_data}{"scores"}{"fr"};
$product_ref->{"ecoscore_grade"} = $product_ref->{ecoscore_data}{"grades"}{"fr"};
$product_ref->{"ecoscore_tags"} = [$product_ref->{ecoscore_grade}];

if ($missing_data_warning) {
Expand Down Expand Up @@ -1187,11 +1198,14 @@ sub compute_ecoscore_origins_of_ingredients_adjustment($) {
epi_value => round($epi_value),
};

$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_scores"} = \%transportation_scores;
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_values"} = {};
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"values"} = {};

foreach my $cc (@ecoscore_countries_enabled_sorted) {
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_score_" . $cc} = $transportation_scores{$cc};
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_value_" . $cc} = round($transportation_scores{$cc} / 6.66);
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"value_" . $cc} = round($epi_value)
+ $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_value_" . $cc};
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_values"}{$cc} = round($transportation_scores{$cc} / 6.66);
$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"values"}{$cc} = round($epi_value)
+ $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_values"}{$cc};
}

# Add a warning if the only origin is en:unknown
Expand Down Expand Up @@ -1402,16 +1416,11 @@ sub localize_ecoscore ($$) {
my $product_ref = shift;

# Localize the Eco-Score fields that depends on the country of the request
if (defined $product_ref->{"ecoscore_grade_" . $cc}) {
$product_ref->{"ecoscore_grade"} = $product_ref->{"ecoscore_grade_" . $cc};
}
if (defined $product_ref->{"ecoscore_score_" . $cc}) {
$product_ref->{"ecoscore_score"} = $product_ref->{"ecoscore_grade_" . $cc};
}
if ((defined $product_ref->{ecoscore_data}) and (defined $product_ref->{ecoscore_data}{"score_" . $cc})) {

if ((defined $product_ref->{ecoscore_data}) and (defined $product_ref->{ecoscore_data}{"scores"}{$cc})) {

$product_ref->{ecoscore_data}{"score"} = $product_ref->{ecoscore_data}{"score_" . $cc};
$product_ref->{ecoscore_data}{"grade"} = $product_ref->{ecoscore_data}{"grade_" . $cc};
$product_ref->{ecoscore_data}{"score"} = $product_ref->{ecoscore_data}{"scores"}{$cc};
$product_ref->{ecoscore_data}{"grade"} = $product_ref->{ecoscore_data}{"grades"}{$cc};

$product_ref->{"ecoscore_score"} = $product_ref->{ecoscore_data}{"score"};
$product_ref->{"ecoscore_grade"} = $product_ref->{ecoscore_data}{"grade"};
Expand All @@ -1420,13 +1429,13 @@ sub localize_ecoscore ($$) {
if (defined $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}) {

$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"value"}
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"value_" . $cc};
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"values"}{$cc};

$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_score"}
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_score_" . $cc};
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_scores"}{$cc};

$product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_value"}
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_value_" . $cc};
= $product_ref->{ecoscore_data}{adjustments}{origins_of_ingredients}{"transportation_values"}{$cc};

# For each origin, we also add its score (EPI + transporation to country of request)
# so that clients can show which ingredients contributes the most to the origins of ingredients bonus / malus
Expand Down
Loading

0 comments on commit 22dccb8

Please sign in to comment.