Skip to content

4. Ćwiczenie praktyczne – wersje 1 i 2

4.1. Zadanie

Image

Powyższa tabela pozwala obliczyć podatek w uproszczonym przypadku podatnika, który ma do zadeklarowania wyłącznie swoje wynagrodzenie. Jak wskazuje uwaga (1), tak obliczony podatek jest podatkiem przed zastosowaniem trzech mechanizmów:

  • ograniczenia współczynnika rodzinnego, które ma zastosowanie w przypadku wysokich dochodów;
  • ulgi i obniżki podatkowe, które mają zastosowanie w przypadku niskich dochodów;

W związku z tym obliczenie podatku obejmuje następujące etapy [http://impotsurlerevenu.org/comprendre-le-calcul-de-l-impot/1217-calcul-de-l-impot-2019.php]:

Image

Proponujemy napisanie programu umożliwiającego obliczenie podatku podatnika w uproszczonym przypadku, gdy podatnik ma do zadeklarowania wyłącznie swoje wynagrodzenie:

4.1.1. Obliczanie podatku brutto

Podatek brutto można obliczyć w następujący sposób:

Najpierw oblicza się liczbę udziałów podatnika:

    • każdy z rodziców wnosi 1 udział;
    • dwoje pierwszych dzieci wnosi po 1/2 udziału;
    • kolejne dzieci wnoszą po jednej części:

Liczba udziałów wynosi zatem:

  • nbParts=1+nbEnfants*0,5+(liczbaDzieci-2)*0,5, jeśli pracownik nie jest żonaty;
  • nbParts = 2 + nbEnfants * 0,5 + (nbEnfants – 2) * 0,5, jeśli jest żonaty;

gdzie nbEnfants oznacza liczbę dzieci;

  • oblicza się dochód podlegający opodatkowaniu R = 0,9 * S, gdzie S to roczne wynagrodzenie;
  • oblicza się współczynnik rodzinny QF = R / nbParts;
  • oblicza się podatek brutto I na podstawie następujących danych (2019):
9964
0
0
27519
0,14
1394,96
73779
0,3
5798
156 244
0,41
13913,69
0
0,45
20163,45

Każdy wiersz zawiera 3 pola: champ1, champ2, champ3. Aby obliczyć podatek I, szukamy pierwszego wiersza, w którym QF ≤ pole1, i pobieramy wartości z tego wiersza. Na przykład dla pracownika pozostającego w związku małżeńskim, mającego dwoje dzieci i roczne wynagrodzenie S w wysokości 50 000 euro:

Dochód podlegający opodatkowaniu: R = 0,9 * S = 45 000

Liczba udziałów: nbParts = 2 + 2 * 0,5 = 3

Współczynnik rodzinny: QF = 45 000 / 3 = 15 000

Pierwszy wiersz, w którym QF <= pole1, wygląda następująco:

    27519        0.14    1394.96

Podatek I wynosi zatem 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*3]=2115. Podatek jest zaokrąglany w dół do najbliższego euro.

Jeśli już w pierwszym wierszu zachodzi relacja QF ≤ pole1, wówczas podatek wynosi zero.

Jeśli QF jest takie, że warunek QF <= pole1 nigdy nie jest spełniony, wówczas stosuje się współczynniki z ostatniego wiersza. W tym przypadku:

    0            0.45        20163.45

co daje podatek brutto I = 0,45*R – 20163,45*nbParts.

4.1.2. Ograniczenie ilorazu rodzinnego

Image

Aby sprawdzić, czy ma zastosowanie limit ilorazu rodzinnego QF, ponownie obliczamy podatek brutto bez uwzględnienia dzieci. Nadal dla pracownika pozostającego w związku małżeńskim, mającego dwoje dzieci i roczne wynagrodzenie S w wysokości 50 000 euro:

Dochód podlegający opodatkowaniu: R = 0,9 * S = 45 000

Liczba udziałów: nbParts=2 (nie uwzględnia się już dzieci)

Współczynnik rodzinny: QF = 45000/2 = 22500

Pierwszy wiersz, w którym QF <= pole1, wygląda następująco:

    27519        0.14    1394.96

Podatek I wynosi zatem 0,14*R – 1394,96*nbParts=[0,14*45000-1394,96*2]=3510.

Maksymalna ulga na dzieci: 1551 * 2 = 3102 euro

Podatek minimalny: 3510 – 3102 = 408 euro

Podatek brutto z uwzględnieniem 3 udziałów, wynoszący 2115 euro, jest wyższy od podatku minimalnego wynoszącego 408 euro, dlatego w tym przypadku nie ma zastosowania limit rodzinny.

Ogólnie rzecz biorąc, podatek brutto jest większy niż (podatek1, podatek2), gdzie:

  • [impôt1]: to podatek brutto obliczony z uwzględnieniem dzieci;
  • [impôt2]: to podatek brutto obliczony bez uwzględnienia dzieci i pomniejszony o maksymalną ulgę (w tym przypadku 1551 euro na pół części) związaną z dziećmi;

4.1.3. Obliczanie ulgi

Image

Nadal w przypadku pracownika pozostającego w związku małżeńskim, mającego dwoje dzieci i roczne wynagrodzenie S w wysokości 50 000 euro:

Podatek brutto (2115) uzyskany w poprzednim etapie jest niższy niż 2627 euro dla pary (1595 euro dla osoby samotnej): w związku z tym ma zastosowanie ulga. Oblicza się ją w następujący sposób:

obniżka = próg (para = 1970 / osoba samotna = 1196) – 0,75 * podatek brutto

obniżka = 1970 – 0,75 * 2115 = 383,75, zaokrąglone do 384 euro.

Nowy podatek brutto = 2115 – 384 = 1731 euro

4.1.4. Obliczenie ulgi podatkowej

Image

Poniżej określonego progu od podatku brutto wynikającego z powyższych obliczeń przyznaje się ulgę w wysokości 20%. W 2019 r. progi te wynoszą:

  • osoba samotna: 21 037 euro;
  • para: 42 074 euro; (liczba 37 968 użyta w powyższym przykładzie wydaje się błędna);

Próg ten zwiększa się o wartość: 3797 * (liczba pół-udziałów przypisanych dzieciom).

W przypadku pracownika pozostającego w związku małżeńskim, mającego dwoje dzieci i roczne wynagrodzenie S w wysokości 50 000 euro:

  • jego dochód podlegający opodatkowaniu (45 000 euro) jest niższy od progu (42 074 + 2 * 3797) = 49 668 euro;
  • ma zatem prawo do 20-procentowej ulgi podatkowej: 1731 * 0,2 = 346,2 euro, zaokrąglone do 347 euro;
  • podatek brutto podatnika wynosi: 1731 – 347 = 1384 euro;

4.1.5. Obliczenie podatku netto

Na tym zakończymy nasze obliczenia: podatek netto do zapłaty wyniesie 1384 euro. W rzeczywistości podatnik może skorzystać z innych ulg, w szczególności z tytułu darowizn na rzecz organizacji pożytku publicznego lub ogólnego.

4.1.6. Przypadek wysokich dochodów

Nasz poprzedni przykład dotyczy większości pracowników najemnych. Jednak w przypadku wysokich dochodów obliczenie podatku przebiega inaczej.

4.1.6.1. Ograniczenie 10-procentowej ulgi od rocznych dochodów

W większości przypadków dochód podlegający opodatkowaniu oblicza się według wzoru: R = 0,9 * S, gdzie S oznacza roczne wynagrodzenie. Nazywa się to 10-procentową ulgą. Ulga ta podlega ograniczeniu. W 2019 r.:

  • nie może przekraczać 12 502 euro;
  • nie może być niższa niż 437 euro;

Weźmy na przykład pracownika niebędącego w związku małżeńskim, bezdzietnego, o rocznym wynagrodzeniu w wysokości 200 000 euro:

  • 10-procentowa redukcja wynosi 200 000 euro > 12 502 euro. Zostaje zatem ograniczona do 12 502 euro;

4.1.6.2. Ograniczenie ilorazu rodzinnego

Rozważmy przypadek, w którym ma zastosowanie limit rodzinny przedstawiony w akapicie [link]. Weźmy pod uwagę parę z trójką dzieci i rocznym dochodem w wysokości 100 000 euro. Przeanalizujmy kolejne etapy obliczeń:

  • odliczenie w wysokości 10 % wynosi 10 000 euro < 12 502 euro. Dochód podlegający opodatkowaniu R wynosi zatem 100 000 – 10 000 = 90 000 euro;
  • para posiada nbParts = 2 + 0,5 × 2 + 1 = 4 części;
  • jej współczynnik rodzinny wynosi zatem QF = R / nbParts = 90 000 / 4 = 22 500 euro;
  • jej podatek brutto I1 z uwzględnieniem dzieci wynosi I1=0,14*90 000 - 1 394,96*4 = 7 020 euro;
  • jego podatek brutto I2 bez dzieci:
    • QF = 90 000 / 2 = 45 000 euro;
    • I2 = 0,3 × 90 000 – 5 798 × 2 = 15 404 euro;
    • zasada ograniczenia ilorazu rodzinnego stanowi, że korzyść wynikająca z posiadania dzieci nie może przekroczyć (1551 × 4 półczęści) = 6204 euro. W tym przypadku wynosi ona jednak I2-I1 = 15404 – 7020 = 8384 euro, a więc jest wyższa niż 6204 euro;
    • podatek brutto jest zatem przeliczany jako I3 = I2-6204 = 15 404 – 6 204 = 9 200 euro;

Para ta nie będzie miała prawa do ulgi ani obniżki, a jej ostateczny podatek wyniesie 9200 euro.

4.1.7. Dane oficjalne

Obliczanie podatku jest skomplikowane. W całym dokumencie testy będą przeprowadzane na podstawie poniższych przykładów. Wyniki pochodzą z symulatora urzędu skarbowego [https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.htm]:

Podatnik
Oficjalne wyniki
Wyniki algorytmu przedstawionego w dokumencie
Para z dwójką dzieci i rocznym dochodem w wysokości 55 555 euro
Podatek = 2815 euro
Stawka podatkowa = 14 %
Podatek = 2814 euro
Stawka podatkowa = 14 %
Para z dwójką dzieci i rocznym dochodem w wysokości 50 000 euro
Podatek = 1385 euro
Ulga = 720 euro
Ulga = 0 euro
Stawka podatkowa = 14 %
Podatek = 1384 euro
Odliczenie = 384 euro
Ulga = 347 euro
Stawka podatkowa = 14 %
Para z trójką dzieci i rocznym dochodem w wysokości 50 000 euro
Podatek = 0 euro
Odliczenie = 384 euro
Ulga = 346 euro
Stawka podatkowa = 14 %
Podatek = 0 euro
Odliczenie = 720 euro
Ulga = 0 euro
Stawka podatkowa = 14 %
Osoba samotna z dwójką dzieci i rocznym dochodem w wysokości 100 000 euro
Podatek = 19 884 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Podatek = 19 884 euro
Dodatek = 4480 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Osoba samotna z trójką dzieci i rocznym dochodem w wysokości 100 000 euro
Podatek = 16 782 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Podatek = 16 782 euro
Dodatek = 7176 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Para z trójką dzieci i rocznym dochodem w wysokości 100 000 euro
Podatek = 9200 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 30 %
Podatek = 9200 euro
Dodatek = 2180 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 30 %
Para z pięciorgiem dzieci i rocznym dochodem w wysokości 100 000 euro
Podatek = 4230 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 14 %
Podatek = 4230 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 14 %
Osoba samotna bez dzieci, z rocznym dochodem w wysokości 100 000 euro
Podatek = 22 986 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Podatek = 22 986 euro
Dodatek = 0 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Para z dwójką dzieci i rocznym dochodem w wysokości 30 000 euro
Podatek = 0 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 0 %
Podatek = 0 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 0 %
Osoba samotna bez dzieci, z rocznym dochodem w wysokości 200 000 euro
Podatek = 64 211 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 45 %
Podatek = 64 210 euro
Dodatek = 7498 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 45 %
Para z trójką dzieci i rocznym dochodem w wysokości 200 000 euro
Podatek = 42 843 euro
Ulga = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %
Podatek = 42 842 euro
Dodatek = 17 283 euro
Odliczenie = 0 euro
Ulga = 0 euro
Stawka podatkowa = 41 %

W powyższym przykładzie jako dopłatę określa się kwotę, którą osoby o wysokich dochodach płacą dodatkowo z powodu dwóch czynników:

  • ograniczenie ulgi podatkowej do 10% rocznego dochodu;
  • ograniczenie współczynnika rodzinnego;

Wskaźnika tego nie udało się zweryfikować, ponieważ symulator urzędu skarbowego go nie podaje.

Widać, że algorytm zawarty w dokumencie za każdym razem podaje prawidłową kwotę podatku, jednak z marginesem błędu wynoszącym 1 euro. Margines ten wynika z zaokrągleń. Wszystkie kwoty są czasami zaokrąglane w górę do pełnego euro, a czasami w dół do pełnego euro. Ponieważ nie znałem oficjalnych zasad, kwoty w algorytmie zawartym w dokumencie zostały zaokrąglone:

  • w górę do pełnego euro w przypadku obniżek i zniżek;
  • w dół do pełnego euro w przypadku dopłat i podatku końcowego;

W dalszej części zostaną przeprowadzone testy w celu sprawdzenia poprawności wyników. Zostaną one wykonane na przykładach z poprzedniej tabeli przy dopuszczalnym marginesie błędu wynoszącym 1 euro.

4.2. Struktura drzewa skryptów

Image

4.3. Wersja 1

4.3.1. Algorytm

Przedstawiamy pierwszy program, w którym:

  • dane niezbędne do obliczenia podatku są na stałe zapisane w kodzie w postaci tabel i stałych;
  • dane podatników (stan cywilny, dzieci, wynagrodzenie) znajdują się w pierwszym pliku tekstowym [taxpayersdata.txt];
  • wyniki obliczeń podatku (stan cywilny, liczba dzieci, wynagrodzenie, podatek) są zapisane w drugim pliku tekstowym o nazwie [resultats.txt];

Skrypt [version-01/main.php] wygląda następująco:


<?php

// ścisłe typy dla parametrów funkcji
declare(strict_types=1);

// stałe globalne
define("PLAFOND_QF_DEMI_PART", 1551);
define("PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION", 21037);
define("PLAFOND_REVENUS_COUPLE_POUR_REDUCTION", 42074);
define("VALEUR_REDUC_DEMI_PART", 3797);
define("PLAFOND_DECOTE_CELIBATAIRE", 1196);
define("PLAFOND_DECOTE_COUPLE", 1970);
define("PLAFOND_IMPOT_COUPLE_POUR_DECOTE", 2627);
define("PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE", 1595);
define("ABATTEMENT_DIXPOURCENT_MAX", 12502);
define("ABATTEMENT_DIXPOURCENT_MIN", 437);

// definiowanie stałych lokalnych
$DATA = "taxpayersdata.txt";
$RESULTATS = "resultats.txt";
$limites = array(9964, 27519, 73779, 156244, 0);
$coeffR = array(0, 0.14, 0.3, 0.41, 0.45);
$coeffN = array(0, 1394.96, 5798, 13913.69, 20163.45);

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

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

// przetwarzanie bieżącego wiersza pliku danych
while ($ligne = fgets($data, 100)) {
  // usuwanie ewentualnego znaku końca linii
  $ligne = cutNewLineChar($ligne);
  // pobierane są 3 pola: żonaty:dzieci:wynagrodzenie, które tworzą $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // oblicza się podatek
  $result = calculImpot($marié, (int) $enfants, (float) $salaire, $limites, $coeffR, $coeffN);
  // wynik zapisuje się w pliku wyników
  $result = ["marié" => $marié, "enfants" => $enfants, "salaire" => $salaire] + $result;
  fputs($résultats, \json_encode($result, JSON_UNESCAPED_UNICODE) . "\n");
  // kolejny rekord
}
// zamykamy pliki
fclose($data);
fclose($résultats);

// koniec
exit;

// --------------------------------------------------------------------------
function cutNewLinechar(string $ligne): string {
  // usuwa się znak końca linii z $ligne, jeśli istnieje
  $L = strlen($ligne);  // długość wiersza
  while (substr($ligne, $L - 1, 1) === "\n" or substr($ligne, $L - 1, 1) === "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // koniec
  return($ligne);
}

// obliczenie podatku
// --------------------------------------------------------------------------
function calculImpot(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {

  // wynik
  return ["impôt" => floor($impot), "surcôte" => $surcôte, "décôte" => $décôte, "réduction" => $réduction, "taux" => $taux];
}

// --------------------------------------------------------------------------
function calculImpot2(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {

  // wynik
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}

// revenuImposable=wynagrodzenieRoczne-ulga
// odliczenie ma wartość minimalną i maksymalną
function getRevenuImposable(float $salaire): float {

  // wynik
  return floor($revenuImposable);
}

// oblicza ewentualną obniżkę
function getDecote(string $marié, float $salaire, float $impots): float {

  // wynik
  return ceil($décôte);
}

// oblicza ewentualną obniżkę
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {
  /
  // wynik
  return ceil($réduction);
}

Plik danych taxpayersdata.txt (stan cywilny, dzieci, wynagrodzenie):

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

Pliki résultats.txt (stan cywilny, dzieci, wynagrodzenie, podatek, dopłata, ulga, obniżka, stawka podatkowa) zawierające uzyskane wyniki:

{"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}

Uwagi

  • wiersz 4: wymuszamy ścisłe przestrzeganie typów parametrów funkcji;
  • wiersze 7–16: definicja wszystkich stałych niezbędnych do obliczenia podatku;
  • wiersz 19: nazwa pliku tekstowego zawierającego dane podatników (stan cywilny, dzieci, wynagrodzenie);
  • wiersz 20: nazwa pliku tekstowego zawierającego wyniki (stan cywilny, dzieci, wynagrodzenie, podatek) obliczeń podatku;
  • wiersze 21–23: trzy tabele danych określające różne progi podatkowe stosowane w obliczeniach podatku;
  • wiersze 26–30: otwarcie w trybie odczytu pliku z danymi podatników za pomocą funkcji [r]. Funkcja [fopen] zwraca wartość logiczną FALSE, jeśli otwarcie pliku nie powiodło się;
  • wiersze 33–37: otwarcie pliku wyników w trybie zapisu za pomocą funkcji [w];
  • wiersze 40–51: pętla odczytu wierszy (małżonek, dzieci, wynagrodzenie) z pliku danych podatników;
  • wiersz 40: funkcja [fgets] odczytuje 100 znaków i zatrzymuje się przy pierwszym napotkanym znaku końca wiersza. W tym przypadku wszystkie wiersze mają mniej niż 100 znaków. Jeśli napotkano znak końca wiersza, jest on uwzględniony w zwracanym ciągu znaków. Po osiągnięciu końca pliku funkcja [fgets] zwraca wartość FALSE;
  • wiersz 42: znak końca wiersza zostaje usunięty;
  • wiersz 44: pobierane są składniki (małżonek, dzieci, wynagrodzenie) z tego wiersza;
  • wiersz 46: obliczany jest podatek. Wynik jest zwracany w postaci tablicy asocjacyjnej (wiersz 76);
  • wiersz 48: do pobranej wcześniej tablicy dodaje się klucze [marié, enfants, salaire];
  • wiersz 49: wynik jest zapisywany w pliku wyników w postaci ciągu znaków jSON;
  • wiersze 53–54: po pełnym przetworzeniu pliku danych podatników pliki są zamykane;
  • wiersz 60: funkcja usuwająca znak końca wiersza z wiersza $ligne. Znakiem końca wiersza jest ciąg „\r\n” w systemach Windows oraz „\n” w systemach Unix. Wynikiem jest ciąg wejściowy bez znaku końca wiersza.
  • wiersze 63–64: substr($chaîne,$début,$taille) to podciąg ciągu $chaîne, zaczynający się od znaku $début i zawierający co najwyżej $taille znaków;

Funkcja [calculImpot] jest następująca:


// stałe globalne
define("PLAFOND_QF_DEMI_PART", 1551);

// obliczenie podatku
// --------------------------------------------------------------------------
function calculImpot(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {
  // $marié: tak, nie
  // $enfants: liczba dzieci
  // $salaire: roczne wynagrodzenie
  // $limites, $coeffR, $coeffN: tabele danych umożliwiające obliczenie podatku
  //
  // obliczenie podatku z uwzględnieniem dzieci
  $result1 = calculImpot2($marié, $enfants, $salaire, $limites, $coeffR, $coeffN);
  $impot1 = $result1["impôt"];
  // obliczenie podatku bez uwzględnienia dzieci
  if ($enfants != 0) {
    $result2 = calculImpot2($marié, 0, $salaire, $limites, $coeffR, $coeffN);
    $impot2 = $result2["impôt"];
    // zastosowanie limitu ilorazu rodzinnego
    if ($enfants < 3) {
      // $PLAFOND_QF_DEMI_PART euro na pierwsze dwoje dzieci
      $impot2 = $impot2 - $enfants * PLAFOND_QF_DEMI_PART;
    } else {
      // $PLAFOND_QF_DEMI_PART euro na pierwsze dwoje dzieci, dwukrotność tej kwoty na kolejne
      $impot2 = $impot2 - 2 * PLAFOND_QF_DEMI_PART - ($enfants - 2) * 2 * PLAFOND_QF_DEMI_PART;
    }
  } else {
    $impot2 = $impot1;
    $result2 = $result1;
  }
  // bierzemy najwyższy podatek wraz z odpowiednią stawką i dopłatą
  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"];
  }
  // obliczenie ewentualnej ulgi
  $décôte = getDecote($marié, $salaire, $impot);
  $impot -= $décôte;
  // obliczenie ewentualnej ulgi podatkowej
  $réduction = getRéduction($marié, $salaire, $enfants, $impot);
  $impot -= $réduction;
  // wynik
  return ["impôt" => floor($impot), "surcôte" => $surcôte, "décôte" => $décôte, "réduction" => $réduction, "taux" => $taux];
}

// --------------------------------------------------------------------------
function calculImpot2(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {

  // wynik
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}

// revenuImposable=wynagrodzenieRoczne-odliczenie
// odliczenie w wysokości 10% ma wartość minimalną i maksymalną
function getRevenuImposable(float $salaire): float {

}

// oblicza ewentualną obniżkę
function getDecote(string $marié, float $salaire, float $impots): float {

  // wynik
  return ceil($décôte);
}

// oblicza ewentualną obniżkę
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {

  // wynik
  return ceil($réduction);
}

Uwagi

  • wiersz 10: podatek brutto jest obliczany z uwzględnieniem dzieci. Otrzymujemy wynik w postaci ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]] z:
    • [‘impôt’]: podatek brutto;
    • [‘surcôte’]: kwota dopłaty, jeśli występuje. Występuje ona, gdy ulga w wysokości 10% przekracza próg 12 502 euro;
    • [‘taux’]: stawka podatkowa podatnika;
  • wiersz 11: podatek brutto [impot1] do zapłaty;
  • wiersze 13–14: jeśli podatnik ma co najmniej jedno dziecko, obliczenie podatku przeprowadza się ponownie przy użyciu tych samych danych, ale z założeniem, że nie ma dzieci. To drugie obliczenie jest konieczne, aby sprawdzić, czy ulga wynikająca z posiadania dzieci (nbParts*coeffN) przekracza określony próg;
  • wiersz 15: podatek brutto [impot2] do zapłaty;
  • wiersze 16–23: w przypadku podatku brutto [impot2] uwzględnia się teraz dzieci: każda 1/2 części wynikająca z posiadania dzieci pozwala na obniżkę o [PLAFOND_QF_DEMI_PART] euro;
  • wiersze 25–26: przypadek, w którym podatnik nie ma dzieci. W takim przypadku obliczanie wartości [impot2] nie ma sensu. Jest ona równa wartości [impot1];
  • wiersze 29–37: obliczono dwie kwoty podatku brutto [impot1, impot2]. Urząd skarbowy wybiera wyższą z nich. Otrzymujemy kwotę podatku brutto [impot];
  • wiersze 39–40: kwota brutto [impot] może podlegać obniżce;
  • wiersze 42–43: kwota brutto [impot] może podlegać obniżce;
  • wiersz 45: [impot] stanowi teraz podatek netto do zapłaty. Zwracamy wyniki;

Funkcja [calculImpot2] wygląda następująco:


// --------------------------------------------------------------------------
function calculImpot2(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {
  // $marié: tak, nie
  // $enfants: liczba dzieci
  // $salaire: roczne wynagrodzenie
  // $limites, $coeffR, $coeffN: tabele danych umożliwiające obliczenie podatku
  //
  // liczba udziałów
  $marié = strtolower($marié);
  if ($marié === "oui") {
    $nbParts = $enfants / 2 + 2;
  } else {
    $nbParts = $enfants / 2 + 1;
  }
  // 1 część na dziecko, począwszy od trzeciego
  if ($enfants >= 3) {
    // pół udziału dodatkowo na każde dziecko od trzeciego
    $nbParts += 0.5 * ($enfants - 2);
  }
  // dochód podlegający opodatkowaniu
  $revenuImposable = getRevenuImposable($salaire);
  // dopłata
  $surcôte = floor($revenuImposable - 0.9 * $salaire);
  // z powodu problemów z zaokrągleniem
  if ($surcôte < 0) {
    $surcôte = 0;
  }
  // współczynnik rodzinny
  $quotient = $revenuImposable / $nbParts;
  // jest umieszczany na końcu tabeli limitów, aby zatrzymać następującą po niej pętlę
  $limites[count($limites) - 1] = $quotient;
  // obliczenie podatku
  $i = 0;
  while ($quotient > $limites[$i]) {
    $i++;
  }
  // ponieważ umieszczono $quotient na końcu tablicy $limites, poprzednia pętla
  // nie może wykraczać poza tablicę $limites
  // teraz można obliczyć podatek
  $impôt = floor($revenuImposable * $coeffR[$i] - $nbParts * $coeffN[$i]);
  // wynik
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}

// revenuImposable = roczne wynagrodzenie – ulga
// odliczenie ma wartość minimalną i maksymalną
function getRevenuImposable(float $salaire): float {
  
  // wynik
  return floor($revenuImposable);
}

Komentarze

  • stosuje się tutaj obliczenie podatku według tzw. skali progresywnej;
  • wiersz 9: strtolower($chaîne) zamienia $chaîne na małe litery;
  • wiersze 10–19: obliczanie liczby udziałów podatnika;
  • wiersz 21: dochód podlegający opodatkowaniu oblicza się za pomocą funkcji. Jak bowiem zauważono, nie zawsze wynosi on 0,9*revenusAnnuels. Odliczenie w wysokości 10% jest bowiem ograniczone do 12 502 euro;
  • wiersz 23: obliczenie ewentualnej dopłaty, jeśli dochód podlegający opodatkowaniu jest wyższy niż 0,9*revenusAnnuels;
  • wiersze 25–27: koryguje fakt, że z powodu błędów zaokrąglenia czasami otrzymujemy wartość [$surcôte=-1];
  • wiersz 29: iloraz rodzinny;
  • wiersze 30–36: iloraz ten pozwala określić przedział podatkowy podatnika;
  • wiersz 40: po ustaleniu przedziału podatkowego podatnika można obliczyć jego podatek brutto. Funkcja floor($x) zwraca liczbę całkowitą bezpośrednio mniejszą od [$x];
  • wiersz 42: zwracane są obliczone informacje;

Funkcja [getRevenuImposable] ma następującą postać:


// stałe globalne
define("ABATTEMENT_DIXPOURCENT_MAX", 12502);
define("ABATTEMENT_DIXPOURCENT_MIN", 437);

// revenuImposable=wynagrodzenieRoczne-odliczenie
// odliczenie ma wartość minimalną i maksymalną
function getRevenuImposable(float $salaire): float {
  // odliczenie w wysokości 10% wynagrodzenia
  $abattement = 0.1 * $salaire;
  // odliczenie to nie może przekroczyć wartości ABATTEMENT_DIXPOURCENT_MAX
  if ($abattement > ABATTEMENT_DIXPOURCENT_MAX) {
    $abattement = ABATTEMENT_DIXPOURCENT_MAX;
  }
  // odliczenie nie może być niższe niż ABATTEMENT_DIXPOURCENT_MIN
  if ($abattement < ABATTEMENT_DIXPOURCENT_MIN) {
    $abattement = ABATTEMENT_DIXPOURCENT_MIN;
  }
  // dochód podlegający opodatkowaniu
  $revenuImposable = $salaire - $abattement;
  // wynik
  return floor($revenuImposable);
}

Uwagi

  • wiersz 5: standardowa ulga wynosi 10% rocznego wynagrodzenia;
  • wiersze 7–9: odliczenie nie może przekroczyć maksymalnego odliczenia [ABATTEMENT_DIXPOURCENT_MAX];
  • wiersze 10–13: odliczenie nie może być niższe od minimalnego odliczenia [ABATTEMENT_DIXPOURCENT_MIN];
  • wiersz 15: obliczenie dochodu podlegającego opodatkowaniu;

Funkcja [getDecote] ma następujący przebieg:


// stałe ogólne
define("PLAFOND_DECOTE_CELIBATAIRE", 1196);
define("PLAFOND_DECOTE_COUPLE", 1970);
define("PLAFOND_IMPOT_COUPLE_POUR_DECOTE", 2627);
define("PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE", 1595);

// oblicza ewentualną dyskontę
function getDecote(string $marié, float $salaire, float $impots): float {
  // początkowo odliczenie wynosi zero
  $décôte = 0;
  // maksymalna kwota podatku uprawniająca do ulgi
  $plafondImpôtPourDécôte = $marié === "oui" ? PLAFOND_IMPOT_COUPLE_POUR_DECOTE : PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE;
  if ($impots < $plafondImpôtPourDécôte) {
    // maksymalna kwota ulgi
    $plafondDécôte = $marié === "oui" ? PLAFOND_DECOTE_COUPLE : PLAFOND_DECOTE_CELIBATAIRE;
    // obniżka teoretyczna
    $décôte = $plafondDécôte - 0.75 * $impots;
    // ulga nie może przekroczyć kwoty podatku
    if ($décôte > $impots) {
      $décôte = $impots;
    }
    // brak obniżki <0
    if ($décôte < 0) {
      $décôte = 0;
    }
  }
  // wynik
  return ceil($décôte);
}

Uwagi

  • wiersz 6: maksymalna kwota podatku brutto uprawniająca do ulgi podatkowej. Kwota ta jest różna dla osób samotnych i par;
  • wiersz 7: czy podatnik ma prawo do ulgi;
  • wiersz 11: wzór na obniżkę. [plafondDécôte] to maksymalna kwota obniżki. Ta maksymalna kwota jest obliczana w wierszu 9. Również w tym przypadku zależy ona od sytuacji podatnika – czy jest on w związku małżeńskim, czy jest osobą samotną;
  • wiersze 13–15: ulga nie może przekraczać kwoty podatku brutto do zapłaty. Ma to miejsce na przykład wtedy, gdy wartość [impots] w wierszu 11 wynosi 0;
  • wiersze 17–19: aby uniknąć zaokrąglenia do -1;

Funkcja [getRéduction] ma następujący wygląd:


// stałe globalne
define("PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION", 21037);
define("PLAFOND_REVENUS_COUPLE_POUR_REDUCTION", 42074);
define("VALEUR_REDUC_DEMI_PART", 3797);

// oblicza ewentualną ulgę
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {
  // pułap dochodów uprawniający do ulgi w wysokości 20%
  $plafondRevenuPourRéduction = $marié === "oui" ? PLAFOND_REVENUS_COUPLE_POUR_REDUCTION : PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION;
  $plafondRevenuPourRéduction += $enfants * VALEUR_REDUC_DEMI_PART;
  if ($enfants > 2) {
    $plafondRevenuPourRéduction += ($enfants - 2) * VALEUR_REDUC_DEMI_PART;
  }
  // dochód podlegający opodatkowaniu
  $revenuImposable = getRevenuImposable($salaire);
  // ulga
  $réduction = 0;
  if ($revenuImposable < $plafondRevenuPourRéduction) {
    // ulga w wysokości 20%
    $réduction = 0.2 * $impots;
  }
  // wynik
  return ceil($réduction);
}

Uwagi

  • wiersze 4–10: aby uzyskać prawo do ulgi podatkowej, dochód podlegający opodatkowaniu (wiersz 10) musi być niższy od pułapu obliczonego w wierszach 4–8;
  • wiersze 13–16: jeśli podatnik spełnia warunki, przysługuje mu ulga podatkowa w wysokości 20% (wiersz 15);

4.3.2. Wyniki

Plik danych taxpayersdata.txt (stan cywilny, dzieci, wynagrodzenie):

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

Pliki résultats.txt (stan cywilny, dzieci, wynagrodzenie, podatek, dopłata, ulga, obniżka, stawka podatkowa) zawierające uzyskane wyniki:

{"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}

Uzyskane wyniki są zgodne z wynikami uzyskanymi za pomocą symulatora urzędu skarbowego.

4.3.3. Wniosek

Algorytm obliczania podatku, nawet w przypadkach uważanych za proste, jest złożony. Nie będziemy już do niego wracać. W kolejnych wersjach jego rdzeń pozostanie ten sam, pomimo pewnych zmian w prezentacji. Skupimy się zatem wyłącznie na tych ostatnich.

4.4. Wersja 2

4.4.1. Zmiany

W poprzedniej wersji dane niezbędne do obliczenia podatku były zakodowane na stałe w postaci stałych i tablic. Metoda ta jest niedopuszczalna. W nowej wersji dane te zostały przeniesione do pliku jSON:

Image

Zawartość pliku [taxadmindata.json] jest następująca:


{
    "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],
    "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
}

Nowa wersja [version-02/main.php] wygląda następująco:


<?php

// ścisłe przestrzeganie zadeklarowanych typów parametrów funkcji
declare (strict_types=1);

// definicja stałych
$TAXPAYERSDATA = "taxpayersdata.txt";
$RESULTATS = "resultats.txt";
$TAXADMINDATA = "taxadmindata.json";

// pobieramy zawartość pliku z danymi podatkowymi
$fileContents = \file_get_contents($TAXADMINDATA);
$erreur = FALSE;
// błąd?
if (!$fileContents) {
  // odnotowujemy błąd
  $erreur = TRUE;
  $message = "Le fichier des données [$TAXADMINDATA] n'existe pas";
}

if (!$erreur) {
  // pobieranie kodu jSON z pliku konfiguracyjnego do tablicy asocjacyjnej
  $taxAdminData = \json_decode($fileContents, true);
  // błąd?
  if (!$taxAdminData) {
    // odnotowuje się błąd
    $erreur = TRUE;
    $message = "Le fichier de données jSON [$TAXADMINDATA] n'a pu être exploité correctement";
  }
}

// błąd?
if ($erreur) {
  print "$message\n";
  exit;
}

// otwieranie pliku wyników
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  // wyjście
  exit;
}

// otwieranie pliku z danymi podatników
$taxpayersdata = fopen($TAXPAYERSDATA, "r");
if (!$taxpayersdata) {
  print "Impossible d'ouvrir le fichier des contribuables [$TAXPAYERSDATA]\n";
  // wyjście
  exit;
}

// przetwarzanie bieżącego wiersza pliku danych
while ($ligne = fgets($taxpayersdata, 100)) {
  // usuwanie ewentualnego znacznika końca wiersza
  $ligne = cutNewLineChar($ligne);
  // pobierane są 3 pola: stan cywilny:liczba dzieci:wynagrodzenie, które tworzą $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // oblicza się podatek
  $result = calculImpot($taxAdminData, $marié, (int) $enfants, (int) $salaire);
  // wynik zapisuje się w pliku wyników
  $result = ["marié" => $marié, "enfants" => $enfants, "salaire" => $salaire] + $result;
  fputs($résultats, \json_encode($result, JSON_UNESCAPED_UNICODE) . "\n");
  // kolejny rekord
}
// zamykamy pliki
fclose($taxpayersdata);
fclose($résultats);

// koniec
exit;

// --------------------------------------------------------------------------
function cutNewLinechar(string $ligne) {

  // koniec
  return($ligne);
}

// obliczenie podatku
// --------------------------------------------------------------------------
function calculImpot(array $taxAdminData, string $marié, int $enfants, float $salaire) {
  // $marié: tak, nie
  // $enfants: liczba dzieci
  // $salaire: roczne wynagrodzenie
  // $taxAdminData: dane z urzędu skarbowego
  //
  // obliczenie podatku z uwzględnieniem dzieci
  $result1 = calculImpot2($taxAdminData, $marié, $enfants, $salaire);
  $impot1 = $result1["impôt"];
  // obliczenie podatku bez uwzględnienia dzieci
  if ($enfants != 0) {
    $result2 = calculImpot2($taxAdminData, $marié, 0, $salaire);
    $impot2 = $result2["impôt"];
    // zastosowanie limitu ilorazu rodzinnego
    if ($enfants < 3) {
      // $PLAFOND_QF_DEMI_PART euro na pierwsze dwoje dzieci
      $impot2 = $impot2 - $enfants * $taxAdminData["PLAFOND_QF_DEMI_PART"];
    } else {
      // $PLAFOND_QF_DEMI_PART euro na pierwsze dwoje dzieci, dwukrotnie więcej na kolejne
      $impot2 = $impot2 - 2 * $taxAdminData["PLAFOND_QF_DEMI_PART"] - ($enfants - 2) * 2 * $taxAdminData["PLAFOND_QF_DEMI_PART"];
    }
  } else {
    $impot2 = $impot1;
    $result2 = $result1;
  }
  // bierzemy najwyższy podatek wraz z odpowiednią stawką i dopłatą
  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"];
  }
  // obliczenie ewentualnej ulgi
  $décôte = getDecote($taxAdminData, $marié, $salaire, $impot);
  $impot -= $décôte;
  // obliczenie ewentualnej ulgi podatkowej
  $réduction = getRéduction($taxAdminData, $marié, $salaire, $enfants, $impot);
  $impot -= $réduction;
  // wynik
  return ["impôt" => floor($impot), "surcôte" => $surcôte, "décôte" => $décôte, "réduction" => $réduction, "taux" => $taux];
}

// --------------------------------------------------------------------------
function calculImpot2(array $taxAdminData, string $marié, int $enfants, float $salaire) {
  // $marié: tak, nie

  // wynik
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}

// revenuImposable=wynagrodzenieRoczne-ulga
// ulga ma wartość minimalną i maksymalną
function getRevenuImposable(array $taxAdminData, float $salaire): float {

  // wynik
  return floor($revenuImposable);
}

// oblicza ewentualną obniżkę
function getDecote(array $taxAdminData, string $marié, float $salaire, float $impots): float {

  // wynik
  return ceil($décôte);
}

// oblicza ewentualną redukcję
function getRéduction(array $taxAdminData, string $marié, float $salaire, int $enfants, float $impots): float {

  // wynik
  return ceil($réduction);
}

Komentarze

  • wiersze 11–19: podejmowana jest próba odczytania zawartości pliku jSON o nazwie [TAXADMINDATA];
  • wiersze 21–30: jeśli udało się odczytać plik jSON, jego zawartość jest dekodowana do tablicy asocjacyjnej [$taxAdminData];
  • wiersze 32–36: jeśli w jednej z dwóch poprzednich operacji wystąpił błąd, na konsoli wyświetlany jest komunikat o błędzie i program się zatrzymuje;
  • różnica w stosunku do wersji 01 polega na tym, że tutaj dane (tabele i stałe) urzędu skarbowego znajdują się w tablicy asocjacyjnej [$taxAdminData], podczas gdy w wersji 01 znajdowały się one w tablicach i stałych globalnych. To właśnie globalny charakter tych stałych stanowi różnicę między obiema wersjami:
    • w wersji 01 stałe były znane we wszystkich funkcjach tablicy [main.php];
    • aby uzyskać ten sam wynik w wersji 02, należy przekazać tablicę asocjacyjną [$taxAdminData] jako parametr do wszystkich funkcji (wiersze 83, 129, 138, 145, 152);
  • każda funkcja w wersji 02 musi wykorzystywać zawartość tablicy [$taxAdminData];
  • wiersze 83–126: w funkcji [calculerImpot], tam gdzie wcześniej używano stałych globalnych lub tablic [limites, coeffR, coeffN], teraz wykorzystuje się zawartość tablicy [$taxAdminData] otrzymanej jako parametr (wiersze 99, 102);
  • wszystkie pozostałe funkcje zostały przerobione w ten sam sposób;

Uzyskane wyniki są takie same jak w poprzedniej wersji.

4.4.2. Wniosek

Wersja 02 jest znacznie bardziej elastyczna niż wersja 01. W 2020 r. algorytm obliczania podatku będzie prawdopodobnie taki sam jak w 2019 r. Zmieniły się jedynie progi podatkowe i stałe obliczeniowe. Wystarczy wtedy zaktualizować plik [taxadmindata.json]. W wersji 01 konieczne jest przejście do kodu i zmiana przedziałów podatkowych oraz stałych obliczeniowych. Jest jednak prawdopodobne, że osoby, które muszą zmienić wartości przedziałów podatkowych i stałych obliczeniowych, nie mają dostępu do kodu algorytmu.