Skip to content

4. Toepassingsopgave - IMPOTS

4.1. De opgave

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

  • het aantal aandelen van de werknemer wordt berekend als nbParts = nbEnfants/2 + 1 als hij ongehuwd is, nbEnfants/2+2 als hij getrouwd is, waarbij nbEnfants het aantal kinderen is.
  • vervolgens wordt zijn belastbaar inkomen R = 0,72 * S berekend, waarbij S zijn jaarsalaris is
  • vervolgens wordt zijn gezinscoëfficiënt Q = R/N berekend

we berekenen zijn belasting I op basis van de volgende gegevens

12620,0
0
0
13.190
0,05
631
15640
0,1
1290,5
24.740
0,15
2072,5
31810
0,2
3309,5
39.970
0,25
4900
48360
0,3
6898,5
55790
0,35
9316,5
92970
0,4
12106
127860
0,45
16754,5
151250
0,50
23147,5
172.040
0,55
30710
195.000
0,60
39312
0
0,65
49062

Elke regel heeft 3 velden. Om belasting I te berekenen, zoeken we de eerste regel waar QF <= veld1. Als bijvoorbeeld QF = 30000 is, vinden we de regel

    24740        0.15        2072.5

Belasting I is dan gelijk aan 0,15*R - 2072,5*nbParts. Als QF zodanig is dat de relatie QF<=veld1 nooit geldt, dan worden de coëfficiënten van de laatste regel gebruikt. In dit geval:

    0                0.65        49062

wat de belasting I = 0,65*R – 49062*nbParts oplevert.

4.2. Versie met tabellen (impots_01)

We presenteren een eerste programma waarin:

  • de gegevens die nodig zijn voor de berekening van de belasting in drie tabellen staan (limieten, coeffR, coeffN)
  • de gegevens van de belastingplichtigen (gehuwd, kinderen, salaris) in een eerste tekstbestand staan
  • de resultaten van de belastingberekening (gehuwd, kinderen, salaris, belasting) worden opgeslagen in een tweede tekstbestand

<?php

// definitie van de constanten
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$limites = array(12620, 13190, 15640, 24740, 31810, 39970, 48360, 55790, 92970, 127860, 151250, 172040, 195000);
$coeffR = array(0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65);
$coeffN = array(0, 631, 1290.5, 2072.5, 3309.5, 4900, 6898.5, 9316.5, 12106, 16754.5, 23147.5, 30710, 39312, 49062);

// gegevens inlezen
$data = fopen($DATA, "r");
if (!$data) {
  print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
  exit;
}

// het resultatenbestand openen
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  exit;
}

// de huidige regel van het gegevensbestand wordt verwerkt
while ($ligne = fgets($data, 100)) {
  // eventueel einde-van-regel-teken verwijderen
  $ligne = cutNewLineChar($ligne);
  // de 3 velden 'gehuwd', 'kinderen' en 'salaris' worden opgehaald, die samen $ligne vormen
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // de belasting wordt berekend
  $impôt = calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN);
  // het resultaat wordt in het resultatenbestand opgeslagen
  fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
  // volgende belastingplichtige
}
// de bestanden worden gesloten
fclose($data);
fclose($résultats);

// einde
exit;

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // het einde-van-regel-teken van $ligne wordt verwijderd, indien aanwezig
  $L = strlen($ligne);  // regellengte
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // einde
  return($ligne);
}

// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
  // $marié: ja, nee
  // $enfants: aantal kinderen
  // $salaire: jaarsalaris
  // $limites, $coeffR, $coeffN: de tabellen met gegevens voor de berekening van de belasting
  
  // aantal aandelen
  $marié = strtolower($marié);
  if ($marié == "oui")
    $nbParts = $enfants / 2 + 2;
  else
    $nbParts=$enfants / 2 + 1;
  // een half aandeel extra indien er ten minste 3 kinderen zijn
  if ($enfants >= 3)
    $nbParts+=0.5;
  // belastbaar inkomen
  $revenuImposable = 0.72 * $salaire;
  // gezinsquotiënt
  $quotient = $revenuImposable / $nbParts;
  // wordt aan het einde van de tabel met drempels geplaatst om de daaropvolgende lus te beëindigen
  array_push($limites, $quotient);
  // berekening van de belasting
  $i = 0;
  while ($quotient > $limites[$i])
    $i++;
  // omdat $quotient aan het einde van de tabel $limites is geplaatst, de voorgaande lus
  // mag niet buiten de tabel $limites vallen
  // nu kunnen we de belasting berekenen
  return floor($revenuImposable * $coeffR[$i] - $nbParts * $coeffN[$i]);
}
?>

Het gegevensbestand data.txt (gehuwd, kinderen, salaris):

oui,2,200000
non,2,200000
oui,3,200000
non,3,200000
oui,5,50000
non,0,3000000

De bestanden résultats.txt (gehuwd, kinderen, salaris, belasting) van de verkregen resultaten:

oui:2:200000:22504
non:2:200000:33388
oui:3:200000:16400
non:3:200000:22504
oui:5:50000:0
non:0:3000000:1354938

Opmerkingen

  • regel 4: de naam van het tekstbestand met de gegevens van de belastingplichtigen (gehuwd, kinderen, salaris)
  • regel 5: de naam van het tekstbestand met de resultaten (gehuwd, kinderen, salaris, belasting) van de belastingberekening
  • regels 6-8: de drie tabellen met gegevens die nodig zijn voor de belastingberekening
  • regels 11-15: het bestand met de gegevens van de belastingplichtigen in leesmodus openen
  • regels 18-22: het resultatenbestand openen om te schrijven
  • regel 25: lus voor het lezen van de regels (gehuwd, kinderen, salaris) uit het bestand met belastingplichtigen
  • regel 27: het einde-van-regel-teken wordt verwijderd
  • regel 29: de onderdelen (gehuwd, kinderen, salaris) van de regel worden opgehaald
  • regel 31: de belasting wordt berekend
  • regel 33: de belasting wordt opgeslagen in het resultatenbestand
  • regels 37-38: zodra het belastingplichtigenbestand volledig is verwerkt, worden de bestanden gesloten
  • regel 44: de functie die het einde-van-regel-teken uit een regel $ligne verwijdert. Het einde-van-regel-teken is de tekenreeks "\r\n" op Windows-systemen en "\n" op Unix-systemen. Het resultaat is de invoertekst zonder het einde-van-regel-teken.
  • regels 47-48: substr($chaîne,$début,$taille) is de subreeks van $chaîne die begint bij het teken $début en maximaal $taille tekens bevat.
  • regel 63: strtolower($chaîne) levert $chaîne in kleine letters op
  • regel 76: array_push($tableau,$élément) voegt $élément toe aan het einde van de array $tableau. Merk op dat de array $limites als waarde is doorgegeven aan de functie calculerImpot (regel 56: )). Het toevoegen van dit element gebeurt dus op de kopie van de daadwerkelijke parameter, die zelf ongewijzigd blijft.
  • regel 84: de functie floor($x) levert de gehele getalwaarde op die onmiddellijk kleiner is dan $x.

4.3. Versie met tekstbestanden (impots_02)

Deze nieuwe versie verschilt alleen van de vorige doordat de gegevens ($limites, $coeffR, $coeffN) die nodig zijn voor de berekening van de belasting nu in een tekstbestand staan in de volgende vorm:

Bestand impots.txt:

12620:13190:15640:24740:31810:39970:48360:55790:92970:127860:151250:172040:195000:0
0:0.05:0.1:0.15:0.2:0.25:0.3:0.35:0.4:0.45:0.5:0.55:0.6:0.65
0:631:1290.5:2072.5:3309.5:4900:6898.5:9316.5:12106:16754.5:23147.5:30710:39312:49062

De nieuwe versie leest alleen de gegevens uit het bestand [impots.txt] om deze in drie tabellen ($limites, $coeffR, $coeffN) te plaatsen. We zijn dan weer terug bij het vorige geval. We geven alleen de wijzigingen weer:


<?php

// definitie van de constanten
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";

// de gegevens die nodig zijn voor de berekening van de belasting zijn in het bestand $IMPOTS geplaatst
// met één regel per tabel in de vorm
// val1:val2:val3,...
list($erreur, $limites, $coeffR, $coeffN) = getTables($IMPOTS);

// is er een fout opgetreden?
if ($erreur) {
  print "$erreur\n";
  exit;
}//if
// het inlezen van de gebruikersgegevens
...

// einde
exit;

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // het einde-van-regel-teken van $ligne wordt verwijderd, indien aanwezig
...
}

// --------------------------------------------------------------------------
function calculImpots($marié, $enfants, $salaire, $limites, $coeffR, $coeffN) {
  // $marié: ja, nee
  // $enfants: aantal kinderen
  // $salaire: jaarsalaris
  // $limites, $coeffR, $coeffN: de tabellen met gegevens voor de berekening van de belasting
  ...
}

// --------------------------------------------------------------------------
function getTables($IMPOTS) {
  // $IMPOTS: de naam van het bestand dat de gegevens uit de tabellen $limites, $coeffR en $coeffN bevat
  // bestaat het bestand $IMPOTS?
  if (!file_exists($IMPOTS))
    return array("Le fichier $IMPOTS n'existe pas","","","");
  // het bestand in blokken lezen
  $tables = file($IMPOTS);
  if (!$tables)
    return array("Erreur lors de l'exploitation du fichier $IMPOTS","","","");
  // aanmaken van de 3 tabellen – we gaan ervan uit dat de regels syntactisch correct zijn
  $limites = explode(":", cutNewLineChar($tables[0]));
  $coeffR = explode(":", cutNewLineChar($tables[1]));
  $coeffN = explode(":", cutNewLineChar($tables[2]));
  // einde
  return array("", $limites, $coeffR, $coeffN);
}
?>

Opmerkingen

  • regel 11: de functie getTables($IMPOTS) verwerkt het tekstbestand $IMPOTS om daaruit de drie tabellen te extraheren ($limites, $coeffR, $coeffN). Het weergegeven resultaat is ($erreur, $limites, $coeffR, $coeffN), waarbij $erreur een foutmelding is, die leeg is als er geen fout is opgetreden.
  • regel 40: de functie getTables($IMPOTS).
  • regel 43: de functie files_exists(nom_fichier) retourneert de booleaanse waarde true als het bestand nom_fichier bestaat, en de booleaanse waarde false anders.
  • regel 46: de functie file(nom_fichier) leest het volledige tekstbestand nom_fichier. Ze retourneert een array waarin elk element een regel uit het tekstbestand is. Aangezien het bestand impots.txt in dit geval drie regels tekst bevat, retourneert de functie een array met drie elementen.
  • regels 50-52: de drie opgehaalde regels worden gebruikt om de drie arrays ($limites, $coeffR, $coeffN) aan te maken

De verkregen resultaten zijn dezelfde als in de vorige versie.