Source code for _gettsim.transfers.wohngeld

"""This module provides functions to compute residence allowance (Wohngeld)."""
from _gettsim.config import numpy_or_jax as np
from _gettsim.piecewise_functions import piecewise_polynomial
from _gettsim.shared import add_rounding_spec, dates_active


[docs]def wohngeld_m_hh( wohngeld_nach_vermög_check_m_hh: float, wohngeld_vorrang_hh: bool, wohngeld_kinderzuschl_vorrang_hh: bool, erwachsene_alle_rentner_hh: bool, ) -> float: """Calculate final housing benefit on household level. Parameters ---------- wohngeld_nach_vermög_check_m_hh See :func:`wohngeld_nach_vermög_check_m_hh`. wohngeld_vorrang_hh See :func:`wohngeld_vorrang_hh`. wohngeld_kinderzuschl_vorrang_hh See :func:`wohngeld_kinderzuschl_vorrang_hh`. erwachsene_alle_rentner_hh See :func:`erwachsene_alle_rentner_hh`. Returns ------- """ if ( (not wohngeld_vorrang_hh) and (not wohngeld_kinderzuschl_vorrang_hh) or erwachsene_alle_rentner_hh ): out = 0.0 else: out = wohngeld_nach_vermög_check_m_hh return out
[docs]def wohngeld_abzüge_st_sozialv_m( eink_st_tu: float, ges_rentenv_beitr_m: float, ges_krankenv_beitr_m: float, kind: bool, wohngeld_params: dict, ) -> float: """Calculate housing benefit subtractions on the individual level. Note that eink_st_tu is used as an approximation for taxes on income (as mentioned in § 16 WoGG Satz 1 Nr. 1). Parameters ---------- eink_st_tu See :func:`eink_st_tu`. ges_rentenv_beitr_m See :func:`ges_rentenv_beitr_m`. ges_krankenv_beitr_m See :func:`ges_krankenv_beitr_m`. kind See basic input variable :ref:`kind <kind>`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ abzug_stufen = ( (eink_st_tu > 0) + (ges_rentenv_beitr_m > 0) + (ges_krankenv_beitr_m > 0) ) if kind: out = 0.0 else: out = wohngeld_params["abzug_stufen"][abzug_stufen] return out
[docs]@dates_active(end="2006-12-31", change_name="wohngeld_eink_vor_freib_m") def wohngeld_eink_vor_freib_m_ohne_elterngeld( # noqa: PLR0913 eink_selbst: float, eink_abhängig_beschäftigt: float, kapitaleink_brutto: float, eink_vermietung: float, arbeitsl_geld_m: float, sonstig_eink_m: float, eink_rente_zu_verst_m: float, kind_unterh_erhalt_m: float, unterhaltsvors_m: float, wohngeld_abzüge_st_sozialv_m: float, ) -> float: """Sum gross incomes relevant for housing benefit calculation on individual level and deducting individual housing benefit subtractions. Reference: § 14 WoGG Parameters ---------- eink_selbst See :func:`_eink_selbst`. eink_abhängig_beschäftigt See :func:`eink_abhängig_beschäftigt`. kapitaleink_brutto See :func:`kapitaleink_brutto`. eink_vermietung See :func:`eink_vermietung`. arbeitsl_geld_m See :func:`arbeitsl_geld_m`. sonstig_eink_m See :func:`sonstig_eink_m`. eink_rente_zu_verst_m See :func:`eink_rente_zu_verst_m`. kind_unterh_erhalt_m See basic input variable :ref:`kind_unterh_erhalt_m <kind_unterh_erhalt_m>`. unterhaltsvors_m See :func:`unterhaltsvors_m`. Returns ------- """ einkommen = ( eink_selbst + eink_abhängig_beschäftigt + kapitaleink_brutto + eink_vermietung ) / 12 transfers = ( arbeitsl_geld_m + eink_rente_zu_verst_m + kind_unterh_erhalt_m + unterhaltsvors_m ) eink_ind = einkommen + transfers + sonstig_eink_m out = (1 - wohngeld_abzüge_st_sozialv_m) * eink_ind return out
[docs]@dates_active(start="2007-01-01", change_name="wohngeld_eink_vor_freib_m") def wohngeld_eink_vor_freib_m_mit_elterngeld( # noqa: PLR0913 eink_selbst: float, eink_abhängig_beschäftigt: float, kapitaleink_brutto: float, eink_vermietung: float, arbeitsl_geld_m: float, sonstig_eink_m: float, eink_rente_zu_verst_m: float, kind_unterh_erhalt_m: float, unterhaltsvors_m: float, elterngeld_anr_m: float, wohngeld_abzüge_st_sozialv_m: float, ) -> float: """Sum gross incomes relevant for housing benefit calculation on individual level and deducting individual housing benefit subtractions. Reference: § 14 WoGG Parameters ---------- eink_selbst See :func:`_eink_selbst`. eink_abhängig_beschäftigt See :func:`eink_abhängig_beschäftigt`. kapitaleink_brutto See :func:`kapitaleink_brutto`. eink_vermietung See :func:`eink_vermietung`. arbeitsl_geld_m See :func:`arbeitsl_geld_m`. sonstig_eink_m See :func:`sonstig_eink_m`. eink_rente_zu_verst_m See :func:`eink_rente_zu_verst_m`. kind_unterh_erhalt_m See basic input variable :ref:`kind_unterh_erhalt_m <kind_unterh_erhalt_m>`. unterhaltsvors_m See :func:`unterhaltsvors_m`. elterngeld_anr_m See :func:`elterngeld_anr_m`. Returns ------- """ einkommen = ( eink_selbst + eink_abhängig_beschäftigt + kapitaleink_brutto + eink_vermietung ) / 12 transfers = ( arbeitsl_geld_m + eink_rente_zu_verst_m + kind_unterh_erhalt_m + unterhaltsvors_m + elterngeld_anr_m ) eink_ind = einkommen + transfers + sonstig_eink_m out = (1 - wohngeld_abzüge_st_sozialv_m) * eink_ind return out
[docs]def wohngeld_arbeitendes_kind(bruttolohn_m: float, kindergeld_anspruch: bool) -> bool: """Check if children are working. Parameters ---------- bruttolohn_m See basic input variable :ref:`bruttolohn_m <bruttolohn_m>`. kindergeld_anspruch See :func:`kindergeld_anspruch`. Returns ------- """ out = (bruttolohn_m > 0) and kindergeld_anspruch return out
[docs]@dates_active(end="2015-12-31", change_name="wohngeld_eink_freib_m") def wohngeld_eink_freib_m_bis_2015( # noqa: PLR0913 bruttolohn_m: float, wohngeld_arbeitendes_kind: bool, behinderungsgrad: int, alleinerz: bool, kind: bool, anz_kinder_bis_10_tu: int, wohngeld_params: dict, ) -> float: """Calculate housing benefit subtractions for one individual until 2015. Parameters ---------- bruttolohn_m See basic input variable :ref:`bruttolohn_m <bruttolohn_m>`. wohngeld_arbeitendes_kind See :func:`wohngeld_arbeitendes_kind`. behinderungsgrad See basic input variable :ref:`behinderungsgrad <behinderungsgrad>`. alleinerz See basic input variable :ref:`alleinerz <alleinerz>`. kind See basic input variable :ref:`kind <kind>`. anz_kinder_bis_10_tu See :func:`anz_kinder_bis_10_tu`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ freib_behinderung_m = piecewise_polynomial( behinderungsgrad, thresholds=[*list(wohngeld_params["freib_behinderung"]), np.inf], rates=np.array([[0] * len(wohngeld_params["freib_behinderung"])]), intercepts_at_lower_thresholds=[ yearly_v / 12 for yearly_v in wohngeld_params["freib_behinderung"].values() ], ) # Subtraction for single parents and working children if wohngeld_arbeitendes_kind: freib_kinder_m = min( bruttolohn_m, wohngeld_params["freib_kinder_m"]["arbeitendes_kind"] ) elif alleinerz and (not kind): freib_kinder_m = ( anz_kinder_bis_10_tu * wohngeld_params["freib_kinder_m"]["alleinerz"] ) else: freib_kinder_m = 0.0 return freib_behinderung_m + freib_kinder_m
[docs]@dates_active(start="2016-01-01", change_name="wohngeld_eink_freib_m") def wohngeld_eink_freib_m_ab_2016( bruttolohn_m: float, wohngeld_arbeitendes_kind: bool, behinderungsgrad: int, alleinerz: bool, wohngeld_params: dict, ) -> float: """Calculate housing benefit subtracting for one individual since 2016. Parameters ---------- bruttolohn_m See basic input variable :ref:`bruttolohn_m <bruttolohn_m>`. wohngeld_arbeitendes_kind See :func:`wohngeld_arbeitendes_kind`. behinderungsgrad See basic input variable :ref:`behinderungsgrad <behinderungsgrad>`. alleinerz See basic input variable :ref:`alleinerz <alleinerz>`. kind See basic input variable :ref:`kind <kind>`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ freib_behinderung_m = ( wohngeld_params["freib_behinderung"] / 12 if behinderungsgrad > 0 else 0 ) # Subtraction for single parents and working children # ToDo: # Check how to handle subjects that are single parents and also still count # as arbeitendes Kind (are eligible for Kindergeld) if wohngeld_arbeitendes_kind: freib_kinder_m = min( bruttolohn_m, wohngeld_params["freib_kinder_m"]["arbeitendes_kind"] ) elif alleinerz: freib_kinder_m = wohngeld_params["freib_kinder_m"]["alleinerz"] else: freib_kinder_m = 0.0 return freib_behinderung_m + freib_kinder_m
[docs]def wohngeld_eink_m_hh( haushaltsgröße_hh: int, wohngeld_eink_freib_m_hh: float, wohngeld_eink_vor_freib_m_hh: float, wohngeld_params: dict, ) -> float: """Calculate final income relevant for calculation of housing benefit on household level. Reference: § 13 WoGG Parameters ---------- haushaltsgröße_hh See :func:`haushaltsgröße_hh`. wohngeld_eink_freib_m_hh See :func:`wohngeld_eink_freib_m_hh`. wohngeld_eink_vor_freib_m_hh See :func:`wohngeld_eink_vor_freib_m_hh`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ wohngeld_eink_nach_abzug_m_hh = ( wohngeld_eink_vor_freib_m_hh - wohngeld_eink_freib_m_hh ) unteres_eink = wohngeld_params["min_eink"][ min(haushaltsgröße_hh, max(wohngeld_params["min_eink"])) ] out = max(wohngeld_eink_nach_abzug_m_hh, unteres_eink) return float(out)
[docs]def wohngeld_min_miete_m_hh(haushaltsgröße_hh: int, wohngeld_params: dict) -> float: """Calculate minimal monthly rent subject housing benefit calculation on household level. Parameters ---------- haushaltsgröße_hh See :func:`haushaltsgröße_hh`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ out = wohngeld_params["min_miete"][ min(haushaltsgröße_hh, max(wohngeld_params["min_miete"])) ] return float(out)
[docs]@dates_active(end="2008-12-31", change_name="wohngeld_miete_m_hh") def wohngeld_miete_m_hh_bis_2008( # noqa: PLR0913 mietstufe: int, immobilie_baujahr_hh: int, haushaltsgröße_hh: int, bruttokaltmiete_m_hh: float, wohngeld_min_miete_m_hh: float, wohngeld_params: dict, ) -> float: """Maximal rent subject housing benefit calculation on household level until 2008. Parameters ---------- mietstufe See basic input variable :ref:`mietstufe <mietstufe>`. immobilie_baujahr_hh See basic input variable :ref:`immobilie_baujahr_hh <immobilie_baujahr_hh>`. haushaltsgröße_hh See :func:`haushaltsgröße_hh`. bruttokaltmiete_m_hh See basic input variable :ref:`bruttokaltmiete_m_hh <bruttokaltmiete_m_hh>`. wohngeld_min_miete_m_hh See :func:`wohngeld_min_miete_m_hh`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ max_berücks_personen = wohngeld_params["bonus_sehr_große_haushalte"][ "max_anz_personen_normale_berechnung" ] berücks_personen = min(haushaltsgröße_hh, max_berücks_personen) # Get yearly cutoff in params which is closest and above the construction year # of the property. We assume that the same cutoffs exist for each household # size. params_max_miete = wohngeld_params["max_miete"] selected_bin_index = np.searchsorted( sorted(params_max_miete[1]), immobilie_baujahr_hh, side="left" ) constr_year = list(params_max_miete[1])[selected_bin_index] # Calc maximal considered rent # ToDo: Think about calculating max_definierte_hh_größe already in parameter # ToDo: pre-processing and add it to wohngeld_params max_definierte_hh_größe = max(i for i in params_max_miete if isinstance(i, int)) if haushaltsgröße_hh <= max_definierte_hh_größe: max_miete_m_hh = params_max_miete[haushaltsgröße_hh][constr_year][mietstufe] else: max_miete_m_hh = params_max_miete[max_definierte_hh_größe][constr_year][ mietstufe ] + params_max_miete["jede_weitere_person"][constr_year][mietstufe] * ( berücks_personen - max_definierte_hh_größe ) out = min(bruttokaltmiete_m_hh, max_miete_m_hh) out = max(out, wohngeld_min_miete_m_hh) return out
[docs]@dates_active(start="2009-01-01", change_name="wohngeld_miete_m_hh") def wohngeld_miete_m_hh_ab_2009( # noqa: PLR0912 (see #516) mietstufe: int, haushaltsgröße_hh: int, bruttokaltmiete_m_hh: float, wohngeld_min_miete_m_hh: float, wohngeld_params: dict, ) -> float: """Maximum rent considered in housing benefit since 2009. Parameters ---------- mietstufe See basic input variable :ref:`mietstufe <mietstufe>`. haushaltsgröße_hh See :func:`haushaltsgröße_hh`. bruttokaltmiete_m_hh See basic input variable :ref:`bruttokaltmiete_m_hh <bruttokaltmiete_m_hh>`. wohngeld_min_miete_m_hh See :func:`wohngeld_min_miete_m_hh`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ params_max_miete = wohngeld_params["max_miete"] max_berücks_personen = wohngeld_params["bonus_sehr_große_haushalte"][ "max_anz_personen_normale_berechnung" ] berücks_personen = min(haushaltsgröße_hh, max_berücks_personen) # Calc maximal considered rent max_definierte_hh_größe = max(i for i in params_max_miete if isinstance(i, int)) if haushaltsgröße_hh <= max_definierte_hh_größe: max_miete_m_hh = params_max_miete[haushaltsgröße_hh][mietstufe] else: max_miete_m_hh = ( params_max_miete[max_definierte_hh_größe][mietstufe] + (berücks_personen - max_definierte_hh_größe) * params_max_miete["jede_weitere_person"][mietstufe] ) # Calc heating allowance. Before 2021, heating allowance was not # introduced yet. For this time frame, the respective parameter is # not part of wohngeld_params and heating allowance is set to 0. if "heizkostenentlastung_m" in wohngeld_params: max_def_hh_größe_heating = max( i for i in wohngeld_params["heizkostenentlastung_m"] if isinstance(i, int) ) if "heizkostenentlastung_m" in wohngeld_params: if haushaltsgröße_hh <= max_def_hh_größe_heating: heating_allowance_m = wohngeld_params["heizkostenentlastung_m"][ haushaltsgröße_hh ] else: heating_allowance_m = wohngeld_params["heizkostenentlastung_m"][ max_def_hh_größe_heating ] + (berücks_personen - max_def_hh_größe_heating) * ( wohngeld_params["heizkostenentlastung_m"]["jede_weitere_person"] ) else: heating_allowance_m = 0 # Calc heating cost component. Before 2023, heating cost component was not # introduced yet. For this time frame, the respective parameter is not part # of wohngeld_params and heating cost component is set to 0. if "dauerhafte_heizkostenkomponente_m" in wohngeld_params: max_def_hh_größe_heating = max( i for i in wohngeld_params["dauerhafte_heizkostenkomponente_m"] if isinstance(i, int) ) if "dauerhafte_heizkostenkomponente_m" in wohngeld_params: if haushaltsgröße_hh <= max_def_hh_größe_heating: heating_component_m = wohngeld_params["dauerhafte_heizkostenkomponente_m"][ haushaltsgröße_hh ] else: heating_component_m = wohngeld_params["dauerhafte_heizkostenkomponente_m"][ max_def_hh_größe_heating ] + (berücks_personen - max_def_hh_größe_heating) * ( wohngeld_params["dauerhafte_heizkostenkomponente_m"][ "jede_weitere_person" ] ) else: heating_component_m = 0 # Calc climate component. Before 2023, climate component was not # introduced yet. For this time frame, the respective parameter is not # part of wohngeld_params and climate component is set to 0. if "klimakomponente_m" in wohngeld_params: max_def_hh_größe_heating = max( i for i in wohngeld_params["klimakomponente_m"] if isinstance(i, int) ) if "klimakomponente_m" in wohngeld_params: if haushaltsgröße_hh <= max_def_hh_größe_heating: climate_component_m = wohngeld_params["klimakomponente_m"][ haushaltsgröße_hh ] else: climate_component_m = wohngeld_params["klimakomponente_m"][ max_def_hh_größe_heating ] + (berücks_personen - max_def_hh_größe_heating) * ( wohngeld_params["klimakomponente_m"]["jede_weitere_person"] ) else: climate_component_m = 0 out = min(bruttokaltmiete_m_hh, max_miete_m_hh + climate_component_m) out = max(out, wohngeld_min_miete_m_hh) + heating_allowance_m + heating_component_m return out
[docs]@add_rounding_spec(params_key="wohngeld") def wohngeld_vor_vermög_check_m_hh( haushaltsgröße_hh: int, wohngeld_eink_m_hh: float, wohngeld_miete_m_hh: float, wohngeld_params: dict, ) -> float: """Calcualte preliminary housing benefit. Parameters ---------- haushaltsgröße_hh See :func:`haushaltsgröße_hh`. wohngeld_eink_m_hh See :func:`wohngeld_eink_m_hh`. wohngeld_miete_m_hh See :func:`wohngeld_miete_m_hh`. wohngeld_params See params documentation :ref:`wohngeld_params <wohngeld_params>`. Returns ------- """ max_berücks_personen = wohngeld_params["bonus_sehr_große_haushalte"][ "max_anz_personen_normale_berechnung" ] koeffizienten = wohngeld_params["koeffizienten_berechnungsformel"][ min(haushaltsgröße_hh, max_berücks_personen) ] out = wohngeld_params["faktor_berechnungsformel"] * ( wohngeld_miete_m_hh - ( ( koeffizienten["a"] + (koeffizienten["b"] * wohngeld_miete_m_hh) + (koeffizienten["c"] * wohngeld_eink_m_hh) ) * wohngeld_eink_m_hh ) ) out = max(out, 0.0) if haushaltsgröße_hh > max_berücks_personen: # If more than 12 persons, there is a lump-sum on top. # The maximum is still capped at `wohngeld_miete_m_hh`. out = min( out + wohngeld_params["bonus_sehr_große_haushalte"]["bonus_jede_weitere_person"] * (haushaltsgröße_hh - max_berücks_personen), wohngeld_miete_m_hh, ) return out
def _anteil_personen_in_haushalt_tu( tax_unit_größe_tu: int, haushaltsgröße_hh: int ) -> float: """Calculate the share of tax units in household. ToDo: Change to tax_unit_größe / haushaltsgröße_hh Parameters ---------- tax_unit_größe_tu See :func:`tax_unit_größe_tu`. haushaltsgröße_hh See :func:`haushaltsgröße_hh`. Returns ------- """ return tax_unit_größe_tu / haushaltsgröße_hh