Skip to content

Commit 9838c45

Browse files
authored
Merge pull request #152 from FEWS-NET/HEA-688/ignore_activities_without_wealth_category
Hea 688/ignore activities without wealth category
2 parents ad64de2 + 88e0dde commit 9838c45

2 files changed

Lines changed: 40 additions & 17 deletions

File tree

apps/common/lookups.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import pandas as pd
1111
from django.contrib.auth.models import User
12+
from django.db.models import Model
1213

1314
from .fields import translation_fields
1415
from .models import (
@@ -31,7 +32,7 @@ class Lookup(ABC):
3132

3233
# The primary key fields for the model being retrieved, typically
3334
# a single auto-incremented surrogate key named `id`
34-
id_fields = None
35+
id_fields = []
3536

3637
# The fields passed from the dataframe that are used to constrain the lookup,
3738
# typically the fields that are foreign keys from the model being looked up to
@@ -346,7 +347,7 @@ def get(self, value: str, **parent_values) -> str | None:
346347
return None
347348

348349
@functools.cache
349-
def get_instance(self, value: str, **parent_values) -> str | None:
350+
def get_instance(self, value: str, **parent_values) -> Model | None:
350351
"""
351352
Return the Django model instance for a single string, or None if there is no match.
352353

pipelines/assets/livelihood_activity.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,14 @@ def get_instances_from_dataframe(
420420
# to the list, provided that it has at least one Livelihood Activity where there is some income,
421421
# expediture or consumption. This excludes empty activities that only contain attributes for,
422422
# for example, 'type_of_milk_sold_or_other_uses'.
423+
# Also ignore any livelihood activities that don't have a Wealth Category component to the Wealth Group
424+
# natural key. These are from blank columns between Wealth Category groups in the BSS, which sometimes
425+
# contain data where values or formulae have been copied across all the columns in a row.
423426
non_empty_livelihood_activities = [
424427
livelihood_activity
425428
for livelihood_activity in livelihood_activities_for_strategy
426-
if any(
429+
if livelihood_activity["wealth_group"][2] # Make sure there is a Wealth Category
430+
and any(
427431
(
428432
field in livelihood_activity
429433
and (livelihood_activity[field] or livelihood_activity[field] == 0)
@@ -432,16 +436,27 @@ def get_instances_from_dataframe(
432436
)
433437
]
434438

435-
# Don't save Livelihood Strategies from the Data worksheet that are captured in more detail
436-
# on the Data2 or Data3 worksheets. These strategies have entries in the Data sheet like 'Construction cash income -- see Data2'
437-
if non_empty_livelihood_activities and re.match(
438-
r"^.*(?:data ?[23]|prochaine feuille)$", livelihood_strategy["activity_label"], re.IGNORECASE
439-
):
440-
non_empty_livelihood_activities = []
439+
# Don't save Livelihood Strategies from the Data worksheet that are captured in more detail on the
440+
# Data2 or Data3 worksheets. These strategies have entries in the Data sheet like
441+
# 'Construction cash income -- see Data2'
442+
if non_empty_livelihood_activities:
443+
# Assertion to prevent linting from complaining about possible None values
444+
assert livelihood_strategy is not None, (
445+
"Found Livelihood Activities from row %s, but there is no Livelihood Strategy defined." % row
446+
)
447+
if re.match(
448+
r"^.*(?:data ?[23]|prochaine feuille)$", livelihood_strategy["activity_label"], re.IGNORECASE
449+
):
450+
non_empty_livelihood_activities = []
441451

442452
if non_empty_livelihood_activities:
443453
# Finalize the livelihood strategy and activities, making various adjustments for quirks in the BSS
444454

455+
# Assertion to prevent linting from complaining about possible None values
456+
assert livelihood_strategy is not None, (
457+
"Found Livelihood Activities from row %s, but there is no Livelihood Strategy defined." % row
458+
)
459+
445460
# Copy the product_id for MilkProduction and ButterProduction the previous livelihood strategy if
446461
# necessary.
447462
if (
@@ -468,15 +483,22 @@ def get_instances_from_dataframe(
468483
country_id=livelihood_zone_baseline.livelihood_zone.country_id,
469484
)
470485
and previous_livelihood_activities_for_strategy
471-
and "milking_animals" in previous_livelihood_strategy["attribute_rows"]
472-
and "milking_animals" not in livelihood_strategy["attribute_rows"]
473486
):
474-
livelihood_strategy["attribute_rows"]["milking_animals"] = row
475-
for i in range(len(previous_livelihood_activities_for_strategy)):
476-
if "milking_animals" in previous_livelihood_activities_for_strategy[i]:
477-
livelihood_activities_for_strategy[i]["milking_animals"] = (
478-
previous_livelihood_activities_for_strategy[i]["milking_animals"]
479-
)
487+
# Assertion to prevent linting from complaining about possible None values
488+
assert previous_livelihood_strategy is not None, (
489+
"Found Previous Livelihood Activities from row %s, but there is no Previous Livelihood Strategy defined."
490+
% row
491+
)
492+
if (
493+
"milking_animals" in previous_livelihood_strategy["attribute_rows"]
494+
and "milking_animals" not in livelihood_strategy["attribute_rows"]
495+
):
496+
livelihood_strategy["attribute_rows"]["milking_animals"] = row
497+
for i in range(len(previous_livelihood_activities_for_strategy)):
498+
if "milking_animals" in previous_livelihood_activities_for_strategy[i]:
499+
livelihood_activities_for_strategy[i]["milking_animals"] = (
500+
previous_livelihood_activities_for_strategy[i]["milking_animals"]
501+
)
480502

481503
# Calculate kcals_consumed if the livelihood activity only contains the percentage_kcals.
482504
# This is typical for ButterProduction and consumption of green crops.

0 commit comments

Comments
 (0)