Skip to content

Commit 0f870c0

Browse files
Remove kind input (#1007)
### What problem do you want to solve? Closes #704 This PR attempts to remove the `kind` input variable. This is not a quick and innocent change because `kind` tells GETTSIM much about the role of group members when it comes to transfer eligibility. I chose the following tricks to get rid of `kind`: **Unterhalt** Innocent changes. **Elterngeld / Erziehungsgeld** I didn't want to use the Familiengemeinschaft concept too much because it is not part of the Elterngeldgesetz. I added `ist_leistungsbegründendes_kind` which is True for children that may give rise to an Elterngeld/Erziehungsgeld claim. I also added this concept to the Kindergeld, makes things much clearer IMO. Alternative: As below, analyse the `fg` structure and look for children. **ALG2** Use `ist_kind_in_bedarfsgemeinschaft` / `ist_kind_in_familiengemeinschaft` in order to tell which data raw refers to a child in the SGB II sense. Note that children who live in their own BG are now considered to be "adults" from the POV of GETTSIM's SGB II rules. See #1009. This might be correct or not. Before, users could specify this themselves via the `kind` input. But I doubt anyone did that and we didn't support it systematically, so I wouldn't worry about this too much. **Wohngeld** Innocent changes I believe. I removed a wrong if statement in `abzugsanteil_vom_einkommen_für_steuern_sozialversicherung` and an unnecessary check in `freibetrag_m_bis_2015`. **Kinderzuschlag** I replaced the `erwachsen` conditions with a condition derived from parent-child links (`hat_kind_in_gleicher_bedarfsgemeinschaft`). Again, treatment of children might be wrong here as children who live in their own BG are considered to be adults by GETTSIM. --- In general, we are very bad when it comes to children who claim transfers for themselves (KiZ, ALG2, Wohngeld). But this is a general problem of GETTSIM; this PR highlights it but doesn't make it worse. See issue #1009 and related ones (#750, ...) --------- Co-authored-by: Hans-Martin von Gaudecker <[email protected]>
1 parent ceee61b commit 0f870c0

File tree

286 files changed

+765
-1315
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

286 files changed

+765
-1315
lines changed

outdated_docs/tutorials/policy_functions.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@
7777
"source": [
7878
"def arbeitslosengeld_2__betrag_m_bg(\n",
7979
" arbeitslosengeld_2__anspruchshöhe_m_bg,\n",
80-
" erwachsene_alle_rentenbezieher_hh,\n",
80+
" volljährige_alle_rentenbezieher_hh,\n",
8181
"):\n",
82-
" if erwachsene_alle_rentenbezieher_hh:\n",
82+
" if volljährige_alle_rentenbezieher_hh:\n",
8383
" out = 0.0\n",
8484
" else:\n",
8585
" out = arbeitslosengeld_2__anspruchshöhe_m_bg\n",
@@ -370,7 +370,7 @@
370370
"aggregate_by_p_id_kindergeld = {\n",
371371
" \"kindergeld__anzahl_ansprüche\": {\n",
372372
" \"p_id_to_aggregate_by\": \"kindergeld__p_id_empfänger\",\n",
373-
" \"source\": \"kindergeld__grundsätzlich_anspruchsberechtigt\",\n",
373+
" \"source\": \"kindergeld__ist_leistungsbegründendes_kind\",\n",
374374
" \"agg\": \"sum\",\n",
375375
" },\n",
376376
"}\n",

src/_gettsim/arbeitslosengeld_2/aggregations.py

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,85 @@
22

33
from __future__ import annotations
44

5-
from ttsim.tt_dag_elements import AggType, agg_by_group_function
5+
from typing import TYPE_CHECKING
6+
7+
from ttsim.tt_dag_elements import (
8+
AggType,
9+
agg_by_group_function,
10+
join,
11+
policy_function,
12+
)
13+
14+
if TYPE_CHECKING:
15+
from ttsim.tt_dag_elements.typing import BoolColumn, IntColumn, ModuleType
16+
17+
18+
@policy_function(start_date="2005-01-01")
19+
def ist_kind_in_bedarfsgemeinschaft(
20+
familie__p_id_elternteil_1: IntColumn,
21+
familie__p_id_elternteil_2: IntColumn,
22+
p_id: IntColumn,
23+
bg_id: IntColumn,
24+
xnp: ModuleType,
25+
) -> BoolColumn:
26+
"""Child in a Bedarfsgemeinschaft."""
27+
bg_id_elternteil_1 = join(
28+
foreign_key=familie__p_id_elternteil_1,
29+
primary_key=p_id,
30+
target=bg_id,
31+
value_if_foreign_key_is_missing=-1,
32+
xnp=xnp,
33+
)
34+
bg_id_elternteil_2 = join(
35+
foreign_key=familie__p_id_elternteil_2,
36+
primary_key=p_id,
37+
target=bg_id,
38+
value_if_foreign_key_is_missing=-1,
39+
xnp=xnp,
40+
)
41+
in_gleicher_fg_wie_elternteil_1 = bg_id_elternteil_1 == bg_id
42+
in_gleicher_fg_wie_elternteil_2 = bg_id_elternteil_2 == bg_id
43+
return in_gleicher_fg_wie_elternteil_1 | in_gleicher_fg_wie_elternteil_2
44+
45+
46+
@policy_function(start_date="2005-01-01")
47+
def ist_erwachsener_in_bedarfsgemeinschaft(
48+
ist_kind_in_bedarfsgemeinschaft: bool,
49+
) -> bool:
50+
"""Adult in a Bedarfsgemeinschaft."""
51+
return not ist_kind_in_bedarfsgemeinschaft
652

753

8-
# TODO(@MImmesberger): Many of these keys can go once we have `_eg` for SGB XII.
9-
# https://github.com/iza-institute-of-labor-economics/gettsim/issues/738
10-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
11-
def anzahl_erwachsene_fg(familie__erwachsen: bool, fg_id: int) -> int:
12-
pass
13-
14-
15-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
16-
def anzahl_kinder_fg(familie__kind: bool, fg_id: int) -> int:
17-
pass
18-
19-
20-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
21-
def anzahl_kinder_bis_6_fg(familie__kind_bis_6: bool, fg_id: int) -> int:
22-
pass
23-
24-
25-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
26-
def anzahl_kinder_bis_15_fg(familie__kind_bis_15: bool, fg_id: int) -> int:
27-
pass
28-
29-
30-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
31-
def anzahl_kinder_bis_17_fg(familie__kind_bis_17: bool, fg_id: int) -> int:
54+
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.COUNT)
55+
def anzahl_personen_bg(bg_id: int) -> int:
3256
pass
3357

3458

3559
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
36-
def anzahl_erwachsene_bg(familie__erwachsen: bool, bg_id: int) -> int:
60+
def anzahl_erwachsene_bg(
61+
ist_erwachsener_in_bedarfsgemeinschaft: bool,
62+
bg_id: int,
63+
) -> int:
3764
pass
3865

3966

4067
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
41-
def anzahl_kinder_bg(familie__kind: bool, bg_id: int) -> int:
68+
def anzahl_kinder_bg(ist_kind_in_bedarfsgemeinschaft: bool, bg_id: int) -> int:
4269
pass
4370

4471

45-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.COUNT)
46-
def anzahl_personen_bg(bg_id: int) -> int:
47-
pass
72+
@policy_function(start_date="2005-01-01")
73+
def ist_kind_bis_17_in_bedarfsgemeinschaft(
74+
alter: int, ist_kind_in_bedarfsgemeinschaft: bool
75+
) -> bool:
76+
"""Child under the age of 18 in Bedarfsgemeinschaft."""
77+
return ist_kind_in_bedarfsgemeinschaft and (alter <= 17)
4878

4979

5080
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
51-
def anzahl_kinder_bis_17_bg(familie__kind_bis_17: bool, bg_id: int) -> int:
81+
def anzahl_kinder_bis_17_bg(
82+
ist_kind_bis_17_in_bedarfsgemeinschaft: bool, bg_id: int
83+
) -> int:
5284
pass
5385

5486

@@ -57,16 +89,10 @@ def alleinerziehend_bg(familie__alleinerziehend: bool, bg_id: int) -> bool:
5789
pass
5890

5991

60-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
61-
def anzahl_erwachsene_eg(familie__erwachsen: bool, eg_id: int) -> int:
62-
pass
63-
64-
65-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.SUM)
66-
def anzahl_kinder_eg(familie__kind: bool, eg_id: int) -> int:
67-
pass
68-
69-
70-
@agg_by_group_function(start_date="2005-01-01", agg_type=AggType.COUNT)
71-
def anzahl_personen_eg(eg_id: int) -> int:
72-
pass
92+
@policy_function(start_date="2005-01-01")
93+
def hat_kind_in_gleicher_bedarfsgemeinschaft(
94+
anzahl_kinder_bg: int,
95+
ist_erwachsener_in_bedarfsgemeinschaft: bool,
96+
) -> bool:
97+
"""Has a child in the same Bedarfsgemeinschaft."""
98+
return anzahl_kinder_bg >= 1 and ist_erwachsener_in_bedarfsgemeinschaft

src/_gettsim/arbeitslosengeld_2/arbeitslosengeld_2.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def betrag_m_bg(
1111
vorrangprüfungen__wohngeld_vorrang_vor_arbeitslosengeld_2_bg: bool,
1212
vorrangprüfungen__kinderzuschlag_vorrang_vor_arbeitslosengeld_2_bg: bool,
1313
vorrangprüfungen__wohngeld_und_kinderzuschlag_vorrang_vor_arbeitslosengeld_2_bg: bool,
14-
erwachsene_alle_rentenbezieher_hh: bool,
14+
volljährige_alle_rentenbezieher_hh: bool,
1515
) -> float:
1616
"""Calculate final monthly subsistence payment on household level.
1717
@@ -21,13 +21,13 @@ def betrag_m_bg(
2121
# Alter (SGB XII) is implemented yet. We assume for now that households with only
2222
# retirees are eligible for Grundsicherung im Alter but not for ALG2/Wohngeld. All
2323
# other households are not eligible for SGB XII, but SGB II / Wohngeld. Once this is
24-
# resolved, remove the `erwachsene_alle_rentenbezieher_hh` condition.
24+
# resolved, remove the `volljährige_alle_rentenbezieher_hh` condition.
2525
# https://github.com/iza-institute-of-labor-economics/gettsim/issues/703
2626
if (
2727
vorrangprüfungen__wohngeld_vorrang_vor_arbeitslosengeld_2_bg
2828
or vorrangprüfungen__kinderzuschlag_vorrang_vor_arbeitslosengeld_2_bg
2929
or vorrangprüfungen__wohngeld_und_kinderzuschlag_vorrang_vor_arbeitslosengeld_2_bg
30-
or erwachsene_alle_rentenbezieher_hh
30+
or volljährige_alle_rentenbezieher_hh
3131
):
3232
out = 0.0
3333
else:

src/_gettsim/arbeitslosengeld_2/freibeträge_vermögen.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
from ttsim.tt_dag_elements import policy_function
66

77

8+
# TODO(@MImmesberger): Treatment of children who live in their own BG may be wrong here.
9+
# https://github.com/iza-institute-of-labor-economics/gettsim/issues/1009
810
@policy_function(start_date="2005-01-01", end_date="2022-12-31")
911
def grundfreibetrag_vermögen(
10-
familie__kind: bool,
12+
ist_kind_in_bedarfsgemeinschaft: bool,
1113
alter: int,
1214
geburtsjahr: int,
1315
maximaler_grundfreibetrag_vermögen: float,
@@ -20,7 +22,7 @@ def grundfreibetrag_vermögen(
2022
threshold_years = list(vermögensgrundfreibetrag_je_lebensjahr.keys())
2123
if geburtsjahr <= threshold_years[0]:
2224
out = next(iter(vermögensgrundfreibetrag_je_lebensjahr.values())) * alter
23-
elif (geburtsjahr >= threshold_years[1]) and (not familie__kind):
25+
elif (geburtsjahr >= threshold_years[1]) and (not ist_kind_in_bedarfsgemeinschaft):
2426
out = list(vermögensgrundfreibetrag_je_lebensjahr.values())[1] * alter
2527
else:
2628
out = 0.0
@@ -30,10 +32,12 @@ def grundfreibetrag_vermögen(
3032

3133
# TODO(@MImmesberger): Parameter should be defined as a piecewise_constant.
3234
# https://github.com/iza-institute-of-labor-economics/gettsim/issues/911
35+
# TODO(@MImmesberger): Treatment of children who live in their own BG may be wrong here.
36+
# https://github.com/iza-institute-of-labor-economics/gettsim/issues/1009
3337
@policy_function(start_date="2005-01-01", end_date="2022-12-31")
3438
def maximaler_grundfreibetrag_vermögen(
3539
geburtsjahr: int,
36-
familie__kind: bool,
40+
ist_kind_in_bedarfsgemeinschaft: bool,
3741
obergrenze_vermögensgrundfreibetrag: dict[int, float],
3842
) -> float:
3943
"""Calculate maximal wealth exemptions by year of birth.
@@ -42,7 +46,7 @@ def maximaler_grundfreibetrag_vermögen(
4246
"""
4347
threshold_years = list(obergrenze_vermögensgrundfreibetrag.keys())
4448
obergrenzen = list(obergrenze_vermögensgrundfreibetrag.values())
45-
if familie__kind:
49+
if ist_kind_in_bedarfsgemeinschaft:
4650
out = 0.0
4751
else:
4852
if geburtsjahr < threshold_years[1]:
@@ -101,7 +105,7 @@ def vermögensfreibetrag_bg_bis_2022(
101105
def vermögensfreibetrag_bg_ab_2023(
102106
anzahl_personen_bg: int,
103107
vermögensfreibetrag_in_karenzzeit_bg: float,
104-
arbeitslosengeld_2_bezug_im_vorjahr: bool,
108+
bezug_im_vorjahr: bool,
105109
vermögensfreibetrag_je_person_nach_karenzzeit: dict[str, float],
106110
) -> float:
107111
"""Calculate actual wealth exemptions since 2023.
@@ -110,7 +114,7 @@ def vermögensfreibetrag_bg_ab_2023(
110114
111115
Note: Since 2023, Arbeitslosengeld 2 is referred to as Bürgergeld.
112116
"""
113-
if arbeitslosengeld_2_bezug_im_vorjahr:
117+
if bezug_im_vorjahr:
114118
out = (
115119
anzahl_personen_bg
116120
* vermögensfreibetrag_je_person_nach_karenzzeit["normaler_satz"]

src/_gettsim/arbeitslosengeld_2/inputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
@policy_input(start_date="2023-01-01")
99
def bezug_im_vorjahr() -> bool:
10-
"""Received Arbeitslosengeld II / Bürgergeld in previous year."""
10+
"""Whether the person received Arbeitslosengeld 2 / Bürgergeld in the previous year."""
1111

1212

1313
# TODO(@MImmesberger): Remove input variable eigenbedarf_gedeckt once

src/_gettsim/arbeitslosengeld_2/regelbedarf.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
get_consecutive_int_lookup_table_param_value,
1111
param_function,
1212
policy_function,
13-
policy_input,
1413
)
1514

1615
if TYPE_CHECKING:
@@ -37,9 +36,9 @@ def regelbedarf_m(
3736
@policy_function(start_date="2005-01-01")
3837
def mehrbedarf_alleinerziehend_m(
3938
familie__alleinerziehend: bool,
40-
anzahl_kinder_bis_17_fg: int,
41-
anzahl_kinder_bis_6_fg: int,
42-
anzahl_kinder_bis_15_fg: int,
39+
familie__anzahl_kinder_bis_17_fg: int,
40+
familie__anzahl_kinder_bis_6_fg: int,
41+
familie__anzahl_kinder_bis_15_fg: int,
4342
parameter_mehrbedarf_alleinerziehend: dict[str, float],
4443
) -> float:
4544
"""Mehrbedarf (additional need) for single parents as a share of the Regelsatz.
@@ -54,13 +53,13 @@ def mehrbedarf_alleinerziehend_m(
5453
"""
5554
basis_mehrbedarf = (
5655
parameter_mehrbedarf_alleinerziehend["basis_je_kind_bis_17"]
57-
* anzahl_kinder_bis_17_fg
56+
* familie__anzahl_kinder_bis_17_fg
5857
)
5958

6059
if (
61-
anzahl_kinder_bis_6_fg == 1
62-
or anzahl_kinder_bis_15_fg == 2
63-
or anzahl_kinder_bis_15_fg == 3
60+
familie__anzahl_kinder_bis_6_fg == 1
61+
or familie__anzahl_kinder_bis_15_fg == 2
62+
or familie__anzahl_kinder_bis_15_fg == 3
6463
):
6564
mehrbedarf = max(
6665
parameter_mehrbedarf_alleinerziehend["kind_bis_6_oder_2_3_kinder_bis_15"],
@@ -274,19 +273,14 @@ def kosten_der_unterkunft_m_bis_2022(
274273
return berechtigte_wohnfläche * anerkannte_warmmiete_je_qm_m
275274

276275

277-
@policy_input(start_date="2023-01-01")
278-
def arbeitslosengeld_2_bezug_im_vorjahr() -> bool:
279-
"""Whether the person received Arbeitslosengeld 2 / Bürgergeld in the previous year."""
280-
281-
282276
@policy_function(
283277
start_date="2023-01-01",
284278
leaf_name="kosten_der_unterkunft_m",
285279
)
286280
def kosten_der_unterkunft_m_ab_2023(
287281
bruttokaltmiete_m: float,
288282
heizkosten_m: float,
289-
arbeitslosengeld_2_bezug_im_vorjahr: bool,
283+
bezug_im_vorjahr: bool,
290284
berechtigte_wohnfläche: float,
291285
anerkannte_warmmiete_je_qm_m: float,
292286
) -> float:
@@ -296,7 +290,7 @@ def kosten_der_unterkunft_m_ab_2023(
296290
297291
Note: Since 2023, Arbeitslosengeld 2 is referred to as Bürgergeld.
298292
"""
299-
if arbeitslosengeld_2_bezug_im_vorjahr:
293+
if bezug_im_vorjahr:
300294
out = berechtigte_wohnfläche * anerkannte_warmmiete_je_qm_m
301295
else:
302296
out = bruttokaltmiete_m + heizkosten_m

src/_gettsim/einkommensteuer/einkommensteuer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def alleinerziehend_sn(familie__alleinerziehend: bool, sn_id: int) -> bool:
4040

4141
@agg_by_p_id_function(agg_type=AggType.SUM)
4242
def anzahl_kindergeld_ansprüche_1(
43-
kindergeld__grundsätzlich_anspruchsberechtigt: bool,
43+
kindergeld__ist_leistungsbegründendes_kind: bool,
4444
familie__p_id_elternteil_1: int,
4545
p_id: int,
4646
) -> int:
@@ -49,7 +49,7 @@ def anzahl_kindergeld_ansprüche_1(
4949

5050
@agg_by_p_id_function(agg_type=AggType.SUM)
5151
def anzahl_kindergeld_ansprüche_2(
52-
kindergeld__grundsätzlich_anspruchsberechtigt: bool,
52+
kindergeld__ist_leistungsbegründendes_kind: bool,
5353
familie__p_id_elternteil_2: int,
5454
p_id: int,
5555
) -> int:

src/_gettsim/einkommensteuer/kinderfreibetrag.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def anzahl_kinderfreibeträge(
4242

4343
@agg_by_p_id_function(agg_type=AggType.SUM)
4444
def anzahl_kinderfreibeträge_1(
45-
kindergeld__grundsätzlich_anspruchsberechtigt: bool,
45+
kindergeld__ist_leistungsbegründendes_kind: bool,
4646
p_id_kinderfreibetragsempfänger_1: int,
4747
p_id: int,
4848
) -> int:
@@ -51,7 +51,7 @@ def anzahl_kinderfreibeträge_1(
5151

5252
@agg_by_p_id_function(agg_type=AggType.SUM)
5353
def anzahl_kinderfreibeträge_2(
54-
kindergeld__grundsätzlich_anspruchsberechtigt: bool,
54+
kindergeld__ist_leistungsbegründendes_kind: bool,
5555
p_id_kinderfreibetragsempfänger_2: int,
5656
p_id: int,
5757
) -> int:

0 commit comments

Comments
 (0)