diff --git a/CHANGES.md b/CHANGES.md index 091e73da85..2bf1460742 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,8 @@ releases are available on [Anaconda.org](https://anaconda.org/conda-forge/gettsi ## Unpublished +- {gh}`786` Check directly whether child and parent are in same Bedarfsgemeinschaft for + Kindergeldübertrag ({ghuser}`MImmesberger`). - {gh}`785` Add NotImplementedError to Unterhaltsvorschuss and test whether output from `create_synthetic_data` is enough to compute default targets ({ghuser}`MImmesberger`). - {gh}`772` Add Mindesteinkommen check to Wohngeld, calculate anz_eig_kind_bis_24 diff --git a/src/_gettsim/config.py b/src/_gettsim/config.py index 9c7b645c2e..a50420f20b 100644 --- a/src/_gettsim/config.py +++ b/src/_gettsim/config.py @@ -158,6 +158,9 @@ def set_array_backend(backend: str): "p_id_einstandspartner": int, "vermögen_bedürft": float, "eigenbedarf_gedeckt": bool, + # TODO(@MImmesberger): Remove input variable eigenbedarf_gedeckt once + # Bedarfsgemeinschaften are fully endogenous + # https://github.com/iza-institute-of-labor-economics/gettsim/issues/763 "gemeinsam_veranlagt": bool, "bruttolohn_m": float, "alter": int, diff --git a/src/_gettsim/groupings.py b/src/_gettsim/groupings.py index ec203162d2..b0ab774e9b 100644 --- a/src/_gettsim/groupings.py +++ b/src/_gettsim/groupings.py @@ -23,6 +23,9 @@ def bg_id_numpy( """ Compute the ID of the Bedarfsgemeinschaft for each person. """ + # TODO(@MImmesberger): Remove input variable eigenbedarf_gedeckt once + # Bedarfsgemeinschaften are fully endogenous + # https://github.com/iza-institute-of-labor-economics/gettsim/issues/763 counter = Counter() result = [] diff --git a/src/_gettsim/transfers/arbeitsl_geld_2/kindergelduebertrag.py b/src/_gettsim/transfers/arbeitsl_geld_2/kindergelduebertrag.py index d729941b9c..0325f25672 100644 --- a/src/_gettsim/transfers/arbeitsl_geld_2/kindergelduebertrag.py +++ b/src/_gettsim/transfers/arbeitsl_geld_2/kindergelduebertrag.py @@ -108,7 +108,7 @@ def _diff_kindergeld_kindbedarf_m( # noqa: PLR0913 kindergeld_zur_bedarfsdeckung_m: float, kind_unterh_erhalt_m: float, unterhaltsvors_m: float, - eigenbedarf_gedeckt: bool, + _in_anderer_bedarfsgemeinschaft_als_kindergeldempfänger: bool, ) -> float: """Kindergeld that is used to cover the needs (SGB II) of the parent. @@ -133,19 +133,13 @@ def _diff_kindergeld_kindbedarf_m( # noqa: PLR0913 See :func:`kind_unterh_erhalt_m`. unterhaltsvors_m See :func:`unterhaltsvors_m`. - eigenbedarf_gedeckt - See :func:`eigenbedarf_gedeckt`. + _in_anderer_bedarfsgemeinschaft_als_kindergeldempfänger + See :func:`_in_anderer_bedarfsgemeinschaft_als_kindergeldempfänger`. Returns ------- """ - # TODO (@MImmesberger): Remove `eigenbedarf_gedeckt` conditions once - # Bedarfsgemeinschaft is fully endogenous. This is a temporary fix. Without it, - # Kindergeld would be counted twice as income of the Bedarfsgemeinschaft (one time - # the full amount for the child and one time the Kindergeldübertrag for the parent - - # because the child doesn't drop out of Bedarfsgemeinschaft endogenously). - # https://github.com/iza-institute-of-labor-economics/gettsim/issues/758 fehlbetrag = max( arbeitsl_geld_2_regelbedarf_m_bg - wohngeld_anspruchshöhe_m_bg @@ -155,9 +149,47 @@ def _diff_kindergeld_kindbedarf_m( # noqa: PLR0913 0.0, ) # Bedarf not covered or same Bedarfsgemeinschaft as parents - if not eigenbedarf_gedeckt or fehlbetrag > kindergeld_zur_bedarfsdeckung_m: + if ( + not _in_anderer_bedarfsgemeinschaft_als_kindergeldempfänger + or fehlbetrag > kindergeld_zur_bedarfsdeckung_m + ): out = 0.0 # Bedarf is covered else: out = kindergeld_zur_bedarfsdeckung_m - fehlbetrag return out + + +@policy_info(skip_vectorization=True) +def _in_anderer_bedarfsgemeinschaft_als_kindergeldempfänger( + p_id: numpy.ndarray[int], + p_id_kindergeld_empf: numpy.ndarray[int], + bg_id: numpy.ndarray[int], +) -> numpy.ndarray[bool]: + """True if the person is in a different Bedarfsgemeinschaft than the + Kindergeldempfänger of that person. + + Parameters + ---------- + p_id + See basic input variable :ref:`p_id ` + p_id_kindergeld_empf + See basic input variable :ref:`p_id_kindergeld_empf ` + bg_id + See :func:`bg_id`. + + Returns + ------- + + """ + # Create a dictionary to map p_id to bg_id + p_id_to_bg_id = dict(zip(p_id, bg_id)) + + # Map each p_id_kindergeld_empf to its corresponding bg_id + empf_bg_id = [ + p_id_to_bg_id[empfänger_id] if empfänger_id >= 0 else -1 + for empfänger_id in p_id_kindergeld_empf + ] + + # Compare bg_id array with the mapped bg_ids of p_id_kindergeld_empf + return bg_id != empf_bg_id diff --git a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_kein_kindergelduebertrag.yaml b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_kein_kindergelduebertrag.yaml index c45e67ac81..bf9f7396eb 100644 --- a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_kein_kindergelduebertrag.yaml +++ b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_kein_kindergelduebertrag.yaml @@ -38,13 +38,6 @@ inputs: - false - false - false - eigenbedarf_gedeckt: - - false - - false - - false - # TODO (@MImmesberger): Remove `eigenbedarf_gedeckt` conditions once - # Bedarfsgemeinschaft is fully endogenous. This is a temporary fix. - # https://github.com/iza-institute-of-labor-economics/gettsim/issues/622 kind: - false - true @@ -157,12 +150,12 @@ inputs: - false - false - false - assumed: {} + assumed: + bg_id: + - 0 + - 0 + - 0 outputs: - bg_id: - - 0 - - 0 - - 0 kindergeldübertrag_m: - 0.0 - 0.0 diff --git a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_teilw_kindergelduebertrag.yaml b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_teilw_kindergelduebertrag.yaml index 43c15304ca..c3b1704003 100644 --- a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_teilw_kindergelduebertrag.yaml +++ b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_teilw_kindergelduebertrag.yaml @@ -40,13 +40,6 @@ inputs: - false - false - false - eigenbedarf_gedeckt: - - false - - false - - true - # TODO (@MImmesberger): Remove `eigenbedarf_gedeckt` conditions once - # Bedarfsgemeinschaft is fully endogenous. This is a temporary fix. - # https://github.com/iza-institute-of-labor-economics/gettsim/issues/622 kind: - false - true diff --git a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_voller_kindergelduebertrag.yaml b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_voller_kindergelduebertrag.yaml index 63f648ef9b..34b6332975 100644 --- a/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_voller_kindergelduebertrag.yaml +++ b/src/_gettsim_tests/test_data/arbeitsl_geld_2/2024/alleinerz_voller_kindergelduebertrag.yaml @@ -40,13 +40,6 @@ inputs: - false - false - false - eigenbedarf_gedeckt: - - false - - false - - true - # TODO (@MImmesberger): Remove `eigenbedarf_gedeckt` conditions once - # Bedarfsgemeinschaft is fully endogenous. This is a temporary fix. - # https://github.com/iza-institute-of-labor-economics/gettsim/issues/622 kind: - false - true @@ -159,12 +152,12 @@ inputs: - false - false - false - assumed: {} + assumed: + bg_id: + - 0 + - 0 + - 1 outputs: - bg_id: - - 0 - - 0 - - 1 kindergeldübertrag_m: - 250.0 - 0.0