Skip to content

8. Toepassingsopgave – versie 1

8.1. Het probleem

Image

Met behulp van de bovenstaande tabel kan de belasting worden berekend in het vereenvoudigde geval van een belastingplichtige die alleen zijn salaris hoeft aan te geven. Zoals aangegeven in voetnoot (1), is de aldus berekende belasting de belasting vóór drie mechanismen:

  • de plafonnering van het gezinsquotiënt, die geldt voor hoge inkomens;
  • de belastingvermindering en -korting die van toepassing zijn op lage inkomens;

De berekening van de belasting omvat dus de volgende stappen [http://impotsurlerevenu.org/comprendre-le-calcul-de-l-impot/1217-calcul-de-l-impot-2019.php]:

Image

We willen een programma schrijven waarmee de belasting van een belastingplichtige kan worden berekend in het vereenvoudigde geval waarin de belastingplichtige alleen zijn salaris hoeft aan te geven:

8.1.1. Berekening van de brutobelasting

De bruto belasting kan als volgt worden berekend:

Eerst wordt het aantal aandelen van de belastingplichtige berekend:

  • elke ouder levert 1 aandeel op;
  • de eerste twee kinderen leveren elk een half aandeel op;
  • de volgende kinderen dragen elk 1 aandeel bij:

Het aantal aandelen is dus:

  • nbParts=1+nbEnfants*0,5+(aantalKinderen-2)*0,5 als de werknemer ongehuwd is;
  • aantal delen = 2 + aantal kinderen * 0,5 + (aantal kinderen - 2) * 0,5 als hij getrouwd is;
    • waarbij nbEnfants het aantal kinderen is;
  • het belastbaar inkomen R wordt berekend als R = 0,9 * S, waarbij S het jaarsalaris is;
  • het gezinsquotiënt QF = R / nbParts wordt berekend;
  • de bruto belasting I wordt berekend op basis van de volgende gegevens (2019):
9964
0
0
27519
0,14
1394,96
73779
0,3
5798
156.244
0,4
13913,69
0
0,45
20163,45

Elke regel heeft 3 velden: champ1, champ2, champ3. Om belasting I te berekenen, zoeken we de eerste regel waarbij QF <= veld1 en nemen we de waarden van die regel. Bijvoorbeeld, voor een gehuwde werknemer met twee kinderen en een jaarsalaris S van 50.000 euro:

Belastbaar inkomen: R=0,9*S=45.000

Aantal delen: nbParts = 2 + 2 * 0,5 = 3

Gezinsquotiënt: QF = 45.000 / 3 = 15.000

De eerste regel waarbij QF <= veld1 is, luidt als volgt:

    27519    0.14    1394.96

De belasting I is dan gelijk aan 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*3]=2115. De belasting wordt naar beneden afgerond op de dichtstliggende euro.

Als de relatie QF <= veld1 vanaf de eerste regel geldt, dan is de belasting nul.

Als QF zodanig is dat de relatie QF<=veld1 nooit wordt vervuld, dan worden de coëfficiënten van de laatste regel gebruikt. Hier:

    0    0.45    20163.45

wat de bruto belasting I = 0,45*R – 20163,45*nbParts oplevert.

8.1.2. Maximum van het gezinsquotiënt

Image

Om te bepalen of de maximering van de gezinsquotiënt QF van toepassing is, wordt de bruto belasting opnieuw berekend zonder de kinderen. Nog steeds voor de gehuwde werknemer met twee kinderen en een jaarsalaris S van 50.000 euro:

Belastbaar inkomen: R = 0,9 * S = 45.000

Aantal delen: nbParts = 2 (de kinderen worden niet meer meegeteld)

Gezinsquotiënt: QF = 45.000 / 2 = 22.500

De eerste regel waarbij QF <= veld1 is, luidt als volgt:

    27519    0.14    1394.96

De belasting I is dan gelijk aan 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*2]=3510.

Maximale kinderbijslag: 1551 * 2 = 3102 euro

Minimale belasting: 3510 – 3102 = 408 euro

De reeds berekende bruto belasting met 3 delen, 2115 euro, is hoger dan de minimale belasting van 408 euro, dus de gezinsplafondregeling is hier niet van toepassing.

In het algemeen geldt dat de bruto belasting groter is dan (belasting1, belasting2), waarbij:

  • [impôt1]: de bruto belasting berekend met de kinderen;
  • [impôt2]: de bruto belasting berekend zonder kinderen, verminderd met de maximale vrijstelling (hier 1551 euro per halve aandeel) in verband met de kinderen;

8.1.3. Berekening van de korting

Image

Nog steeds voor de gehuwde werknemer met twee kinderen en een jaarsalaris S van 50.000 euro:

De bruto belasting (2115) uit de vorige stap is lager dan 2627 euro voor een echtpaar (1595 euro voor een alleenstaande): de korting is dus van toepassing. Deze wordt verkregen met de volgende berekening:

korting = drempel (echtpaar = 1970 / alleenstaande = 1196) - 0,75 * bruto belasting

korting = 1970 - 0,75 × 2115 = 383,75, afgerond op 384 euro.

Nieuwe bruto belasting = 2115 - 384 = 1731 euro

8.1.4. Berekening van de belastingvermindering

Image

Onder een bepaalde drempel wordt een korting van 20 % toegepast op de bruto belasting die uit de voorgaande berekeningen voortvloeit. In 2019 gelden de volgende drempels:

  • alleenstaanden: 21.037 euro;
  • paar: 42.074 euro; (het cijfer 37.968 dat in het bovenstaande voorbeeld wordt gebruikt, lijkt onjuist);

Deze drempel wordt verhoogd met de waarde: 3797 * (aantal halve aandelen dat door de kinderen wordt bijgedragen).

Nog steeds voor de gehuwde werknemer met twee kinderen en een jaarsalaris S van 50.000 euro:

  • zijn belastbaar inkomen (45.000 euro) ligt onder de drempel (42.074 + 2 * 3.797) = 49.668 euro;
  • hij heeft dus recht op een vermindering van 20 % van zijn belasting: 1731 * 0,2 = 346,2 euro, afgerond op 347 euro;
  • de bruto belasting van de belastingplichtige bedraagt dan: 1731 – 347 = 1384 euro;

8.1.5. Berekening van de nettobelasting

Onze berekening houdt hier op: de te betalen nettobelasting bedraagt 1384 euro. In de praktijk kan de belastingplichtige profiteren van andere kortingen, met name voor giften aan instellingen van algemeen of openbaar belang.

8.1.6. Gevallen van hoge inkomens

Ons vorige voorbeeld geldt voor de meeste werknemers. Bij hoge inkomens verloopt de belastingberekening echter anders.

8.1.6.1. Maximum voor de korting van 10 % op het jaarinkomen

In de meeste gevallen wordt het belastbaar inkomen berekend met de formule: R = 0,9 * S, waarbij S het jaarsalaris is. Dit wordt de korting van 10 % genoemd. Aan deze korting geldt een maximum. In 2019:

  • mag deze niet hoger zijn dan 12.502 euro;
  • mag deze niet lager zijn dan 437 euro;

Laten we het geval nemen van een ongehuwde werknemer zonder kinderen met een jaarsalaris van 200.000 euro:

  • de vermindering van 10 % bedraagt 200.000 euro > 12.502 euro. Deze wordt dus teruggebracht tot 12.502 euro;

8.1.6.2. Maximum van het gezinsquotiënt

Laten we een geval bekijken waarin de maximering van de gezinsquotiënt, zoals beschreven in de paragraaf |Maximering van de gezinsquotiënt|, van toepassing is. Laten we het geval nemen van een echtpaar met drie kinderen en een jaarinkomen van 100.000 euro. Laten we de stappen van de berekening nog eens doornemen:

  • de aftrek van 10 % bedraagt 10.000 euro < 12.502 euro. Het belastbaar inkomen R bedraagt dus 100.000 - 10.000 = 90.000 euro;
  • het echtpaar heeft nbParts = 2 + 0,5 × 2 + 1 = 4 delen;
  • hun gezinsquotiënt is dus QF = R / nbParts = 90.000 / 4 = 22.500 euro;
  • hun bruto belasting I1 met kinderen bedraagt I1=0,14*90.000-1.394,96*4= 7.020 euro;
  • zijn bruto belasting I2 zonder kinderen:
  • QF = 90.000 / 2 = 45.000 euro;
  • I2 = 0,3 × 90.000 – 5.798 × 2 = 15.404 euro;
  • volgens de regel inzake de maximering van het gezinsquotiënt mag het voordeel dat kinderen opleveren niet hoger zijn dan (1551 × 4 halve delen) = 6204 euro. In dit geval is het echter I2-I1 = 15404 – 7020 = 8384 euro, dus hoger dan 6204 euro;
  • de bruto belasting wordt daarom herberekend als I3 = I2-6204 = 15.404 - 6.204 = 9.200 euro;

Dit echtpaar krijgt geen korting of vermindering en hun uiteindelijke belastingbedrag bedraagt 9200 euro.

8.1.7. Officiële cijfers

De berekening van de belasting is complex. In dit document worden de berekeningen uitgevoerd aan de hand van de volgende voorbeelden. De resultaten zijn afkomstig van de simulator van de belastingdienst |https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.htm|:

Belastingplichtige
Officiële resultaten
Resultaten van het algoritme uit het document
Echtpaar met 2 kinderen en een jaarinkomen van 55.555 euro
Belasting = 2815 euro
Belastingtarief = 14 %
Belasting = 2814 euro
Belastingtarief = 14 %
Echtpaar met 2 kinderen en een jaarinkomen van 50.000 euro
Belasting = 1385 euro
Korting = 720 euro
Korting = 0 euro
Belastingtarief = 14 %
Belasting = 1.384 euro
Korting = 384 euro
Korting = 347 euro
Belastingtarief = 14 %
Echtpaar met 3 kinderen en een jaarinkomen van 50.000 euro
Belasting = 0 euro
Korting = 384 euro
Korting = 346 euro
Belastingtarief = 14 %
Belasting = 0 euro
korting = 720 euro
Korting = 0 euro
Belastingtarief = 14 %
Alleenstaande met 2 kinderen en een jaarinkomen van 100.000 euro
Belasting = 19.884 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Belasting = 19.884 euro
Toeslag = 4.480 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Alleenstaande met 3 kinderen en een jaarinkomen van 100.000 euro
Belasting = 16.782 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Belasting = 16.782 euro
Toeslag = 7.176 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Echtpaar met 3 kinderen en een jaarinkomen van 100.000 euro
Belasting = 9.200 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 30 %
Belasting = 9.200 euro
Toeslag = 2180 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 30 %
Echtpaar met 5 kinderen en een jaarinkomen van 100.000 euro
Belasting = 4230 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 14 %
Belasting = 4.230 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 14 %
Alleenstaand zonder kinderen en met een jaarinkomen van 100.000 euro
Belasting = 22.986 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Belasting = 22.986 euro
Toeslag = 0 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Echtpaar met 2 kinderen en een jaarinkomen van 30.000 euro
Belasting = 0 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 0 %
Belasting = 0 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 0 %
Alleenstaand zonder kinderen en met een jaarinkomen van 200.000 euro
Belasting = 64.211 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 45 %
Belasting = 64.210 euro
Toeslag = 7498 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 45 %
Echtpaar met 3 kinderen en een jaarinkomen van 200.000 euro
Belasting = 42.843 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %
Belasting = 42.842 euro
Toeslag = 17.283 euro
korting = 0 euro
Korting = 0 euro
Belastingtarief = 41 %

Hierboven wordt 'toeslag' genoemd wat mensen met een hoog inkomen extra betalen vanwege twee fenomenen:

  • de maximering van de aftrek van 10 % op het jaarinkomen;
  • de maximering van het gezinsquotiënt;

Deze indicator kon niet worden gecontroleerd, omdat de simulator van de belastingdienst deze niet weergeeft.

We zien dat het algoritme in het document telkens een juiste belasting oplevert, zij het met een foutmarge van 1 euro. Deze foutmarge is het gevolg van afrondingen. Alle bedragen worden soms naar boven afgerond, soms naar beneden. Aangezien ik de officiële regels niet kende, zijn de bedragen in het algoritme van het document afgerond:

  • naar boven afgerond voor kortingen en verminderingen;
  • naar beneden afgerond voor toeslagen en de uiteindelijke belasting;

We gaan verschillende versies van de belastingberekeningsapp ontwikkelen.

8.2. Versie 1

Image

8.2.1. Het hoofdscript

We presenteren een eerste programma waarin:

  • de gegevens die nodig zijn voor de belastingberekening hard gecodeerd zijn in de code in de vorm van lijsten en constanten;
  • de gegevens van de belastingplichtigen (gehuwd, kinderen, salaris) in een eerste tekstbestand [taxpayersdata.txt] staan;
  • de resultaten van de belastingberekening (gehuwd, kinderen, salaris, belasting) worden opgeslagen in een tweede tekstbestand [résultats.txt];

Het script [v-01/main.py] is als volgt:


# modules
import sys

from impots.v01.shared.impôts_module_01 import *

# main -----------------------

# constanten
# belastingplichtigenbestand
DATA = "./data/taxpayersdata.txt"
# resultatenbestand
RESULTATS = "./data/résultats.txt"

try:
    # uitlezen van belastingplichtigengegevens
    tax_payers = get_taxpayers_data(DATA)
    # lijst met resultaten
    results = []
    # de belasting van de belastingplichtigen wordt berekend
    for tax_payer in tax_payers:
        # de belastingberekening retourneert een sleutelwoordenboek
        # ['marié', 'enfants', 'salaire', 'impôt', 'surcôte', 'décôte', 'réduction', 'taux']
        result = calcul_impôt(tax_payer['marié'], tax_payer['enfants'], tax_payer['salaire'])
        # het woordenboek wordt toegevoegd aan de resultatenlijst
        results.append(result)
    # de resultaten worden opgeslagen
    record_results(RESULTATS, results)
except BaseException as erreur:
    # er kunnen verschillende fouten optreden: bestand ontbreekt, onjuiste bestandsinhoud
    # de fout wordt weergegeven en de applicatie wordt afgesloten
    print(f"l'erreur suivante s'est produite : {erreur}]\n")
    sys.exit()

Opmerkingen

  • regel 4: er wordt gebruikgemaakt van de module [impots.v01.modules.impôts_module_01]. Ter herinnering: dit pad wordt gemeten vanaf de hoofdmap van het project PyCharm;
  • regel 10: het bestand [data/taxpayersdata.txt] is als volgt:
oui,2,55555
oui,2,50000
oui,3,50000
non,2,100000
non,3,100000
oui,3,100000
oui,5,100000
non,0,100000
oui,2,30000
non,0,200000
oui,3,200000

Elke regel vertegenwoordigt een tuple van drie elementen [marié / pacsé ou pas, nombre d'enfants, salaire annuel en euros].

  • regel 12: het bestand waarin de resultaten van de belastingberekening voor elke belastingplichtige uit het bestand [taxpayersdata.txt] worden opgeslagen. Het heeft de volgende inhoud:
{'marié': 'oui', 'enfants': 2, 'salaire': 55555, 'impôt': 2814, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'oui', 'enfants': 2, 'salaire': 50000, 'impôt': 1384, 'surcôte': 0, 'décôte': 384, 'réduction': 347, 'taux': 0.14}
{'marié': 'oui', 'enfants': 3, 'salaire': 50000, 'impôt': 0, 'surcôte': 0, 'décôte': 720, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 2, 'salaire': 100000, 'impôt': 19884, 'surcôte': 4480, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'non', 'enfants': 3, 'salaire': 100000, 'impôt': 16782, 'surcôte': 7176, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 3, 'salaire': 100000, 'impôt': 9200, 'surcôte': 2180, 'décôte': 0, 'réduction': 0, 'taux': 0.3}
{'marié': 'oui', 'enfants': 5, 'salaire': 100000, 'impôt': 4230, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 0, 'salaire': 100000, 'impôt': 22986, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 2, 'salaire': 30000, 'impôt': 0, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0}
{'marié': 'non', 'enfants': 0, 'salaire': 200000, 'impôt': 64210, 'surcôte': 7498, 'décôte': 0, 'réduction': 0, 'taux': 0.45}
{'marié': 'oui', 'enfants': 3, 'salaire': 200000, 'impôt': 42842, 'surcôte': 17283, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
  • regel 16: de gegevens van de belastingplichtigen uit het bestand [taxpayersdata.txt] worden opgehaald. Er wordt een lijst met sleutelwoordenboeken [marié, enfants, salaire] opgehaald, waarbij elk woordenboek een belastingplichtige vertegenwoordigt;
  • regels 17-25: de belasting van de belastingplichtigen uit de lijst [taxPayers] wordt berekend. Er wordt een lijst [results] opgehaald, waarvan elk element opnieuw een sleutelwoordenboek [marié, enfants, salaire, impôt, surcôte, décôte, réduction, taux] is;
  • regel 27: de resultatenlijst [results] wordt opgeslagen in het bestand [résultats.txt] in de hierboven weergegeven vorm;
  • regels 28-32: alle uitzonderingen die uit de module [impots.v01.modules.impôts_module_01] kunnen voortkomen, worden opgevangen;

We zullen nu de drie functies toelichten die door het script [main] worden gebruikt:

  • [get_taxpayers_data]: om de gegevens van de belastingplichtigen in te lezen;
  • [calcul_impôt]: om de belasting van deze belastingplichtigen te berekenen;
  • [record_results]: om de resultaten op te slaan in een tekstbestand;

Al deze functies bevinden zich in de module [impots.modules.impôts_module_01].

8.2.2. De module [impots.v01.shared.impôts_module_01]

De functies die nodig zijn voor de belastingberekening zijn gebundeld in de module [impots.v01.shared.impôts_module_01]:

Image

  • in [1]: definitie van de constanten voor de belastingberekening;
  • in [2]: de lijst met functies van de module;

8.2.3. De functie [get_taxpayers_data]

De functie [get_taxpayers_data] is als volgt:


# importen
import codecs


# het inlezen van de gegevens van de belastingplichtigen
# ----------------------------------------
def get_taxpayers_data(taxpayers_filename: str) -> list:
    # het inlezen van belastingplichtigengegevens
    file = None
    try:
        # de lijst met belastingplichtigen
        taxpayers = []
        # het bestand openen
        file = codecs.open(taxpayers_filename, "r", "utf8")
        # de eerste regel van het belastingplichtigenbestand wordt gelezen
        ligne = file.readline().strip()
        # zolang er nog een regel te verwerken is
        while ligne != '':
            # worden de drie velden ‘gehuwd’, ‘kinderen’ en ‘salaris’ opgehaald die de regel vormen
            (marié, enfants, salaire) = ligne.split(",")
            # deze worden toegevoegd aan de lijst met belastingplichtigen
            taxpayers.append({'marié': marié.strip().lower(), 'enfants': int(enfants), 'salaire': int(salaire)})
            # lezen we een nieuwe regel uit het belastingplichtigenbestand
            ligne = file.readline().strip()
        # we geven het resultaat weer
        return taxpayers
    finally:
        # het bestand wordt gesloten als het geopend was
        if file:
            file.close()

Opmerkingen

  • regel 7: [taxpayers_filename] is de naam van het te verwerken bestand. De functie retourneert een lijst;
  • regels 18-24: de lus voor het verwerken van de regels [marié, enfants, salaire] uit het tekstbestand;
  • regel 20: de drie elementen van de regel worden opgehaald. Hier wordt aangenomen dat de regel syntactisch correct is, d.w.z. dat deze inderdaad de drie verwachte elementen bevat;
  • regel 22: er wordt een woordenboek aangemaakt met de sleutels [marié, enfants, salaire] en dit woordenboek wordt toegevoegd aan de lijst [taxPayers];
  • regel 26: zodra het bestand is verwerkt, wordt de lijst [taxPayers] geretourneerd;
  • regels 10-30: merk op dat er geen clausule [catch] is toegevoegd aan [try] in regel 10. De clausule [catch] is niet verplicht. Op regel 27 is een [finally]-clausule toegevoegd om het tekstbestand in alle gevallen te sluiten, ongeacht of er een fout optreedt of niet;
  • deze try/finally-structuur laat een eventuele uitzondering door (er is geen catch). Deze uitzondering wordt doorgegeven aan het hoofdscript [main], dat zal stoppen en de uitzondering weergeven (zie paragraaf |Het hoofdscript|). Dit mechanisme is voor de meeste functies van de module gebruikt;

8.2.4. De functie [calcul_impôt]

De functie [calcul_impôt] is als volgt:


# imports
import codecs
import math

# belastingschijven 2019
limites = [9964, 27519, 73779, 156244, 0]
coeffr = [0, 0.14, 0.3, 0.41, 0.45]
coeffn = [0, 1394.96, 5798, 13913.69, 20163.45]

# constanten voor de berekening van de belasting 2019
PLAFOND_QF_DEMI_PART = 1551
PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION = 21037
PLAFOND_REVENUS_COUPLE_POUR_REDUCTION = 42074
VALEUR_REDUC_DEMI_PART = 3797
PLAFOND_DECOTE_CELIBATAIRE = 1196
PLAFOND_DECOTE_COUPLE = 1970
PLAFOND_IMPOT_COUPLE_POUR_DECOTE = 2627
PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE = 1595
ABATTEMENT_DIXPOURCENT_MAX = 12502
ABATTEMENT_DIXPOURCENT_MIN = 437


# belastingberekening
# ----------------------------------------
def calcul_impôt(marié: str, enfants: int, salaire: int) -> dict:
    # gehuwd: ja, nee
    # kinderen: aantal kinderen
    # salaris: jaarsalaris
    # grenzen, coeffr, coeffn: de tabellen met gegevens voor de berekening van de belasting
    #
    # belastingberekening met kinderen
    result1 = calcul_impôt_2(marié, enfants, salaire)
    impot1 = result1["impôt"]
    # belastingberekening zonder kinderen
    if enfants != 0:
        result2 = calcul_impôt_2(marié, 0, salaire)
        impot2 = result2["impôt"]
        # toepassing van de maximering van het gezinsquotiënt
        if enfants < 3:
            # PLAFOND_QF_DEMI_PART euro voor de eerste 2 kinderen
            impot2 = impot2 - enfants * PLAFOND_QF_DEMI_PART
        else:
            # PLAFOND_QF_DEMI_PART euro voor de eerste twee kinderen, het dubbele voor de volgende
            impot2 = impot2 - 2 * PLAFOND_QF_DEMI_PART - (enfants - 2) * 2 * PLAFOND_QF_DEMI_PART
    else:
        impot2 = impot1
        result2 = result1

    # we nemen de hoogste belasting met het bijbehorende tarief en de bijbehorende toeslag
    if impot1 > impot2:
        impot = impot1
        taux = result1["taux"]
        surcôte = result1["surcôte"]
    else:
        surcôte = impot2 - impot1 + result2["surcôte"]
        impot = impot2
        taux = result2["taux"]

    # berekening van een eventuele korting
    décôte = get_décôte(marié, salaire, impot)
    impot -= décôte
    # berekening van een eventuele belastingvermindering
    réduction = get_réduction(marié, salaire, enfants, impot)
    impot -= réduction
    # resultaat
    return {"marié": marié, "enfants": enfants, "salaire": salaire, "impôt": math.floor(impot), "surcôte": surcôte,
            "décôte": décôte, "réduction": réduction, "taux": taux}

Opmerkingen

  • regels 6-8: de belastingschijven (zie paragraaf |Berekening van de brutobelasting|);
  • regels 11-20: de constanten voor de belastingberekening;
  • merk op dat de elementen die in de regels 5-20 worden geïnitialiseerd, globaal zijn voor de functies die we gaan beschrijven. Ze zijn dus bekend zolang de functie die ze gebruikt geen variabelen met dezelfde namen declareert;
  • de cijfers in de regels 5-20 veranderen elk jaar. Hier zijn het de cijfers voor 2019;
  • regel 25: de functie [calcul_impôt] ontvangt drie parameters:
    • [marié]: ja/nee, geeft aan of de belastingplichtige gehuwd is of een geregistreerd partnerschap heeft;
    • [enfants]: het aantal kinderen;
    • [salaire]: zijn jaarsalaris in euro’s;
  • regels 31-33: berekening van de belasting, rekening houdend met de kinderen;
  • regels 34-47: deze regels implementeren de maximering van het gezinsquotiënt (zie paragraaf |Maximering van het gezinsquotiënt|);
  • regels 49-57: deze regels berekenen het belastingtarief van de belastingplichtige en een eventuele toeslag (zie paragraaf |Gevallen van hoge inkomens|);
  • regels 59-61: berekening van een eventuele korting (zie paragraaf |Berekening van de korting|);
  • regels 62-64: berekening van een eventuele vermindering van de verschuldigde belasting (zie paragraaf |Berekening van de belastingvermindering|);

Het algoritme is vrij complex en we zullen er niet verder op ingaan dan wat in de commentaren staat. Het algoritme implementeert de wijze van belastingberekening zoals beschreven in de paragraaf |Het probleem|.

8.2.5. De functie [calcul_impôt_2]

De functie [calcul_impôt] maakt gebruik van de volgende functie [calcul_impôt_2]:


def calcul_impôt_2(marié: str, enfants: int, salaire: int) -> list:
    # gehuwd: ja, nee
    # kinderen: aantal kinderen
    # salaris: jaarsalaris
    # grenzen, coeffr, coeffn: de tabellen met gegevens voor de berekening van de belasting
    #
    # aantal aandelen
    marié = marié.strip().lower()
    if marié == "oui":
        nb_parts = enfants / 2 + 2
    else:
        nb_parts = enfants / 2 + 1

    # 1 aandeel per kind vanaf het derde
    if enfants >= 3:
        # een half extra aandeel voor elk kind vanaf het derde
        nb_parts += 0.5 * (enfants - 2)

    # belastbaar inkomen
    revenu_imposable = get_revenu_imposable(salaire)
    # toeslag
    surcôte = math.floor(revenu_imposable - 0.9 * salaire)
    # voor afrondingsproblemen
    if surcôte < 0:
        surcôte = 0

    # gezinsquotiënt
    quotient = revenu_imposable / nb_parts
    # wordt aan het einde van de tabel met drempels geplaatst om de daaropvolgende lus te beëindigen
    limites[len(limites) - 1] = quotient
    # berekening van de belasting
    i = 0
    while quotient > limites[i]:
        i += 1
        # omdat de gezinsquotiënt aan het einde van de limiettabel is geplaatst, wordt de voorgaande lus
    # kan niet buiten de grenzen van de limiettabel vallen

    # nu kan de belasting worden berekend
    impôt = math.floor(revenu_imposable * coeffr[i] - nb_parts * coeffn[i])
    # resultaat
    return {"impôt": impôt, "surcôte": surcôte, "taux": coeffr[i]}

Dit algoritme is beschreven in paragraaf 8.1.1.

8.2.6. De functie [get_décôte]

De functie [get_décôte] voert de berekening uit van de eventuele belastingkorting (paragraaf |Berekening van de korting|):


# berekent een eventuele korting
def get_décôte(marié: str, salaire: int, impots: int) -> int:
    # in eerste instantie is de korting nul
    décôte = 0
    # maximumbedrag aan belasting om in aanmerking te komen voor de korting
    plafond_impôt_pour_décôte = PLAFOND_IMPOT_COUPLE_POUR_DECOTE if marié == "oui" else PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE
    if impots < plafond_impôt_pour_décôte:
        # maximumbedrag van de korting
        plafond_décôte = PLAFOND_DECOTE_COUPLE if marié == "oui" else PLAFOND_DECOTE_CELIBATAIRE
        # theoretische korting
        décôte = plafond_décôte - 0.75 * impots
        # de korting mag het belastingbedrag niet overschrijden
        if décôte > impots:
            décôte = impots

        # geen korting <0
        if décôte < 0:
            décôte = 0

    # resultaat
    return math.ceil(décôte)

8.2.7. De functie [get_réduction]

De functie [get_réduction] implementeert de berekening van de eventuele vermindering van de verschuldigde belasting (paragraaf |Berekening van de belastingvermindering|):


# berekent een eventuele korting
def get_réduction(marié: str, salaire: int, enfants: int, impots: int) -> int:
    # de inkomensgrens om in aanmerking te komen voor de korting van 20%
    plafond_revenu_pour_réduction = PLAFOND_REVENUS_COUPLE_POUR_REDUCTION if marié == "oui" else PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION
    plafond_revenu_pour_réduction += enfants * VALEUR_REDUC_DEMI_PART
    if enfants > 2:
        plafond_revenu_pour_réduction += (enfants - 2) * VALEUR_REDUC_DEMI_PART

    # belastbaar inkomen
    revenu_imposable = get_revenu_imposable(salaire)
    # korting
    réduction = 0
    if revenu_imposable < plafond_revenu_pour_réduction:
        # korting van 20%
        réduction = 0.2 * impots

    # resultaat
    return math.ceil(réduction)

8.2.8. De functie [get_revenu_imposable]

De functie [get_revenu_imposable] berekent het belastbaar inkomen op basis van het jaarsalaris:


# revenu_imposable = salaireAnnuel - vrijstelling
# de korting heeft een minimum en een maximum
# ----------------------------------------
def get_revenu_imposable(salaire: int) -> int:
    # aftrek van 10% van het salaris
    abattement = 0.1 * salaire
    # deze korting mag niet hoger zijn dan ABATTEMENT_DIXPOURCENT_MAX
    if abattement > ABATTEMENT_DIXPOURCENT_MAX:
        abattement = ABATTEMENT_DIXPOURCENT_MAX

    # de korting mag niet lager zijn dan ABATTEMENT_DIXPOURCENT_MIN
    if abattement < ABATTEMENT_DIXPOURCENT_MIN:
        abattement = ABATTEMENT_DIXPOURCENT_MIN

    # belastbaar inkomen
    revenu_imposable = salaire - abattement
    # resultaat
    return math.floor(revenu_imposable)

8.2.9. De functie [record_results]

De functie [record_results] slaat de resultaten van de belastingberekening op in een tekstbestand:


# resultaten opslaan in een tekstbestand
# ----------------------------------------
def record_results(results_filename: str, results: list):
    # results_filename: de naam van het tekstbestand waarin de resultaten moeten worden opgeslagen
    # results: de lijst met resultaten in de vorm van een lijst met woordenboeken
    # elk woordenboek wordt op een aparte tekstregel geschreven
    résultats = None
    try:
        # het resultatenbestand openen
        résultats = codecs.open(results_filename, "w", "utf8")
        # verwerking van de belastingplichtigen
        for result in results:
            # het resultaat wordt in het resultatenbestand geschreven
            résultats.write(f"{result}\n")
            # volgende belastingplichtige
    finally:
        # het bestand wordt gesloten als het geopend was
        if résultats:
            résultats.close()

8.2.10. De resultaten

Zoals eerder vermeld, met het volgende belastingplichtigenbestand [taxpayersdata.txt]:

oui,2,55555
oui,2,50000
oui,3,50000
non,2,100000
non,3,100000
oui,3,100000
oui,5,100000
non,0,100000
oui,2,30000
non,0,200000
oui,3,200000

maakt het script [main.py] het volgende bestand [résultats.txt] aan:

{'marié': 'oui', 'enfants': 2, 'salaire': 55555, 'impôt': 2814, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'oui', 'enfants': 2, 'salaire': 50000, 'impôt': 1384, 'surcôte': 0, 'décôte': 384, 'réduction': 347, 'taux': 0.14}
{'marié': 'oui', 'enfants': 3, 'salaire': 50000, 'impôt': 0, 'surcôte': 0, 'décôte': 720, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 2, 'salaire': 100000, 'impôt': 19884, 'surcôte': 4480, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'non', 'enfants': 3, 'salaire': 100000, 'impôt': 16782, 'surcôte': 7176, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 3, 'salaire': 100000, 'impôt': 9200, 'surcôte': 2180, 'décôte': 0, 'réduction': 0, 'taux': 0.3}
{'marié': 'oui', 'enfants': 5, 'salaire': 100000, 'impôt': 4230, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.14}
{'marié': 'non', 'enfants': 0, 'salaire': 100000, 'impôt': 22986, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0.41}
{'marié': 'oui', 'enfants': 2, 'salaire': 30000, 'impôt': 0, 'surcôte': 0, 'décôte': 0, 'réduction': 0, 'taux': 0}
{'marié': 'non', 'enfants': 0, 'salaire': 200000, 'impôt': 64210, 'surcôte': 7498, 'décôte': 0, 'réduction': 0, 'taux': 0.45}
{'marié': 'oui', 'enfants': 3, 'salaire': 200000, 'impôt': 42842, 'surcôte': 17283, 'décôte': 0, 'réduction': 0, 'taux': 0.41}

Deze resultaten komen overeen met de officiële cijfers in de paragraaf |Officiële cijfers|.

Laten we deze versie nu in een consolevenster uitvoeren:


(venv) C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\impots\v01>python main.py
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    from impots.v01.shared.impôts_module_01 import *
ModuleNotFoundError: No module named 'impots'

We krijgen weer een foutmelding die we al eerder zijn tegengekomen: er wordt een module niet gevonden, in dit geval de module [impots]. Ter herinnering: dit betekent dat:

  • de Python-interpreter de mappen in het Python Path één voor één heeft doorzocht;
  • in geen van deze mappen heeft hij een map gevonden waarin een script [impots.py] aanwezig was;

De versie [v02] biedt een oplossing voor dit probleem.