@@ -892,6 +892,78 @@ def get_instances_from_dataframe(
892892 # that is embedded in the ButterProduction calculations in current BSSs
893893 livelihood_activity ["type_of_milk_consumed" ] = MilkProduction .MilkType .WHOLE
894894
895+ # Move the kcals_consumed and percentage_kcals from ButterProduction
896+ # to the associated MilkProduction livelihood activities.
897+ # The current BSSs only record the percentage_kcals for milk and butter consumption combined,
898+ # and don't contain sufficient information to split the kcals_consumed between milk and butter
899+ # (or cheese). However, we want to consider this consumption as part of the MilkProduction
900+ # livelihood strategy, rather than ButterProduction, even though the percentage_kcals
901+ # immediately follow the ButterProduction rows in the BSS.
902+ if (
903+ livelihood_strategy ["strategy_type" ] == "ButterProduction"
904+ and "percentage_kcals" in livelihood_strategy ["attribute_rows" ]
905+ ):
906+ # Find the MilkProduction livelihood strategy
907+ milk_strategy = None
908+ for strategy in reversed (livelihood_strategies ):
909+ if (
910+ strategy ["strategy_type" ] == "MilkProduction"
911+ # Season for the current LivelihoodStrategy hasn't been converted to a natural key yet,
912+ # so coerce it to a list for comparison
913+ and strategy ["season" ] == [livelihood_strategy ["season" ]]
914+ and strategy ["additional_identifier" ] == livelihood_strategy ["additional_identifier" ]
915+ ):
916+ milk_strategy = strategy
917+ break
918+ if not milk_strategy :
919+ raise ValueError (
920+ f"Could not find the MilkProduction Livelihood Strategy associated with "
921+ f"the ButterProduction strategy at row { row } ."
922+ )
923+ milk_activities = {
924+ activity ["wealth_group" ]: activity
925+ for activity in livelihood_activities
926+ if activity ["livelihood_strategy" ]
927+ == milk_strategy ["livelihood_zone_baseline" ]
928+ + [
929+ milk_strategy ["strategy_type" ],
930+ milk_strategy ["season" ][0 ],
931+ milk_strategy ["product_id" ],
932+ milk_strategy ["additional_identifier" ],
933+ ]
934+ }
935+ moved_any = False
936+ for butter_activity in livelihood_activities_for_strategy :
937+ if butter_activity ["percentage_kcals" ] or butter_activity ["percentage_kcals" ] == 0 :
938+ milk_activity = milk_activities .get (butter_activity ["wealth_group" ])
939+ if not milk_activity or "percentage_kcals" in milk_activity :
940+ continue
941+ # We found a matching MilkProduction activity that doesn't already have
942+ # percentage_kcals set, so move the values across
943+ moved_any = True
944+ for field in ["percentage_kcals" , "kcals_consumed" ]:
945+ milk_activity [field ] = butter_activity .pop (field )
946+ if moved_any :
947+ # Add the fields to the MilkProduction strategy's attribute_rows
948+ for field in ["percentage_kcals" , "kcals_consumed" ]:
949+ if (
950+ field not in milk_strategy ["attribute_rows" ]
951+ and field in livelihood_strategy ["attribute_rows" ]
952+ ):
953+ milk_strategy ["attribute_rows" ][field ] = livelihood_strategy ["attribute_rows" ][
954+ field
955+ ]
956+ # If we have moved all of the percentage_kcals and kcals_consumed from the ButterProduction
957+ # livelihood activities, then remove these attributes from the ButterProduction strategy.
958+ for field in ["percentage_kcals" , "kcals_consumed" ]:
959+ if not any (
960+ field in livelihood_activity
961+ and (livelihood_activity [field ] or livelihood_activity [field ] == 0 )
962+ for livelihood_activity in livelihood_activities_for_strategy
963+ ):
964+ for field in ["percentage_kcals" , "kcals_consumed" ]:
965+ del livelihood_strategy ["attribute_rows" ][field ]
966+
895967 # Add the `times_per_year` to FoodPurchase, PaymentInKind and OtherCashIncome,
896968 # because it is not in the current BSSs
897969 if (
0 commit comments