Skip to content

4. تمرين عملي – الإصداران 1 و 2

4.1. المشكلة

Image

يتيح لك الجدول أعلاه حساب الضريبة في الحالة المبسطة للمكلف الذي لا يبلغ سوى عن راتبه. كما هو موضح في الملاحظة (1)، فإن الضريبة المحسوبة بهذه الطريقة هي الضريبة قبل تطبيق الآليات الثلاث التالية:

  • سقف الحصة العائلية، الذي ينطبق على الدخل المرتفع؛
  • الائتمان الضريبي والتخفيض الضريبي اللذان ينطبقان على الدخل المنخفض؛

وبالتالي، يتضمن حساب الضريبة الخطوات التالية [http://impotsurlerevenu.org/comprendre-le-calcul-de-l-impot/1217-calcul-de-l-impot-2019.php]:

Image

نقترح كتابة برنامج لحساب ضريبة دافع الضرائب في الحالة المبسطة لدافع الضرائب الذي لا يبلغ سوى عن راتبه:

4.1.1. حساب الضريبة الإجمالية

يمكن حساب الضريبة الإجمالية على النحو التالي:

أولاً، نحسب عدد الأسهم الخاصة بالمكلف:

    • يساهم كل من الوالدين بحصة واحدة؛
    • يقدم كل من الطفلين الأولين حصة قدرها 1/2؛
    • ويقدم كل من الأبناء المتبقين حصة واحدة:

وبالتالي، فإن عدد الحصص هو:

  • nbParts=1+nbChildren*0.5+(nbChildren-2)*0.5 إذا كان الموظف غير متزوج؛
  • nbParts = 2 + nbChildren * 0.5 + (nbChildren - 2) * 0.5 إذا كان متزوجًا؛

حيث nbChildren هو عدد الأطفال؛

  • نحسب الدخل الخاضع للضريبة R = 0.9 * S، حيث S هو الراتب السنوي؛
  • يُحسب معامل الأسرة QF على النحو التالي: QF = R / nbParts؛
  • نحسب الضريبة الإجمالية I بناءً على البيانات التالية (2019):
9964
0
0
27,519
0.14
1,394.96
73,779
0.3
5,798
156,244
0.41
13,913.69
0
0.45
20163.45

يحتوي كل صف على 3 حقول: الحقلالحقلالحقل 3. لحساب الضريبة I، نبحث عن أول صف حيث QF <= الحقل 1 ونأخذ القيم من ذلك الصف. على سبيل المثال، لموظف متزوج ولديه طفلان وراتب سنوي S قدره 50,000 يورو:

الدخل الخاضع للضريبة: R=0.9*S=45,000

عدد الحصص: nbParts=2+2*0.5=3

نسبة الأسرة: QF=45,000/3=15,000

الصف الأول الذي يكون فيه QF <= field1 هو كما يلي:

    27519        0.14    1394.96

وبالتالي، فإن الضريبة I تساوي 0.14*R – 1394.96*عدد_الأسهم=[0.14*45000-1394.96*3]=2115. يتم تقريب الضريبة لأسفل إلى أقرب يورو.

إذا كان الشرط QF <= field1 صحيحًا في الصف الأول، فإن الضريبة تساوي صفرًا.

إذا كان QF بحيث لا تتحقق الشرط QF <= field1 أبدًا، يتم استخدام المعاملات من السطر الأخير. هنا:

    0            0.45        20163.45

مما يعطي الضريبة الإجمالية I = 0.45*R – 20163.45*nbParts.

4.1.2. الحد الأقصى لمعدل الأسرة

Image

لتحديد ما إذا كان الحد الأقصى لمعدل الأسرة (QF) ينطبق، نعيد حساب الضريبة الإجمالية بدون الأطفال. مرة أخرى، بالنسبة للموظف المتزوج الذي لديه طفلان وراتب سنوي S قدره 50,000 يورو:

الدخل الخاضع للضريبة: R = 0.9 * S = 45,000

عدد الحصص: nbParts=2 (لم يعد يتم احتساب الأطفال)

معدل الأسرة: QF = 45,000 / 2 = 22,500

السطر الأول حيث QF <= field1 هو كما يلي:

    27519        0.14    1394.96

وبالتالي، فإن الضريبة الأولى تساوي 0.14*R – 1394.96*عدد الأسهم = [0.14*45,000 – 1394.96*2] = 3,510.

الحد الأقصى للإعانة المتعلقة بالأطفال: 1551 × 2 = 3102 يورو

الضريبة الدنيا: 3510 – 3102 = 408 يورو

الضريبة الإجمالية مع 3 شرائح ضريبية، والتي تم حسابها بالفعل بمبلغ 2115 يورو، أعلى من الحد الأدنى للضريبة البالغ 408 يورو، لذا لا ينطبق سقف الأسرة هنا.

بشكل عام، يكون إجمالي الضريبة أكبر من (الضريبة 1، الضريبة 2) حيث:

  • [الضريبة 1]: هي الضريبة الإجمالية المحسوبة بما في ذلك الأطفال؛
  • [الضريبة 2]: هي الضريبة الإجمالية المحسوبة بدون الأطفال ومخصومة منها الائتمان الأقصى (هنا 1,551 يورو لكل نصف حصة) المتعلق بالأطفال؛

4.1.3. حساب التخفيض الضريبي

Image

بالنسبة للموظف المتزوج الذي لديه طفلان وراتب سنوي S قدره 50,000 يورو:

الضريبة الإجمالية (2,115) من الخطوة السابقة أقل من 2,627 يورو للزوجين (1,595 يورو للشخص العازب): وبالتالي ينطبق التخفيض الضريبي. ويتم حسابه على النحو التالي:

الخصم = الحد الأدنى (للزوجين = 1,970 / للأعزب = 1,196) - 0.75 * إجمالي الضريبة

الخصم = 1,970 – 0.75 * 2,115 = 383.75، مقربًا إلى 384 يورو.

الضريبة الإجمالية الجديدة = 2,115 – 384 = 1,731 يورو

4.1.4. حساب التخفيض الضريبي

Image

تحت حد معين، يتم تطبيق تخفيض بنسبة 20% على الضريبة الإجمالية الناتجة عن الحسابات السابقة. في عام 2019، كانت الحدود كما يلي:

  • الأفراد: 21,037 يورو؛
  • الأزواج: 42,074 يورو؛ (يبدو أن الرقم 37,968 المستخدم في المثال أعلاه غير صحيح)؛

يتم زيادة هذا الحد بقيمة: 3,797 * (عدد نصف الحصص التي يساهم بها الأبناء).

مرة أخرى، بالنسبة للموظف المتزوج الذي لديه طفلان وراتب سنوي S قدره 50,000 يورو:

  • دخله الخاضع للضريبة (45,000 يورو) أقل من الحد الأدنى (42,074 + 2 × 3,797) = 49,668 يورو؛
  • وبالتالي يحق له الحصول على تخفيض بنسبة 20% في ضريبته: 1,731 * 0.2 = 346.2 يورو، مقربًا إلى 347 يورو؛
  • يصبح إجمالي الضريبة المستحقة على المكلف: 1,731 – 347 = 1,384 يورو؛

4.1.5. حساب الضريبة الصافية

ينتهي حسابنا هنا: سيكون صافي الضريبة المستحقة 1,384 يورو. في الواقع، قد يكون المكلف مؤهلاً للحصول على خصومات أخرى، لا سيما للتبرعات المقدمة إلى المنظمات العامة أو ذات المصلحة العامة.

4.1.6. حالات الدخل المرتفع

ينطبق المثال السابق على غالبية الموظفين. ومع ذلك، يختلف حساب الضريبة بالنسبة لأصحاب الدخل المرتفع.

4.1.6.1. الحد الأقصى للتخفيض بنسبة 10% على الدخل السنوي

في معظم الحالات، يتم حساب الدخل الخاضع للضريبة باستخدام الصيغة: R = 0.9 × S، حيث S هو الراتب السنوي. يُعرف هذا باسم التخفيض بنسبة 10٪. هذا التخفيض محدد بسقف. في عام 2019:

  • لا يمكن أن يتجاوز 12,502 يورو؛
  • لا يمكن أن يقل عن 437 يورو؛

لنأخذ مثالاً لموظف غير متزوج وليس لديه أطفال ويبلغ راتبه السنوي 200,000 يورو:

  • تبلغ نسبة التخفيض البالغة 10% 200,000 يورو > 12,502 يورو. وبالتالي، فإن الحد الأقصى هو 12,502 يورو؛

4.1.6.2. الحد الأقصى لمعدل الأسرة

لنأخذ حالة ينطبق عليها الحد الأقصى للأسرة المذكور في الفقرة المرتبطة. لنأخذ حالة زوجين لديهما ثلاثة أطفال ودخل سنوي قدره 100,000 يورو. لنراجع خطوات الحساب مرة أخرى:

  • الخصم بنسبة 10% هو 10,000 يورو < 12,502 يورو. وبالتالي، فإن الدخل الخاضع للضريبة R هو 100,000 - 10,000 = 90,000 يورو؛
  • يمتلك الزوجان nbParts = 2 + 0.5 * 2 + 1 = 4 حصص؛
  • وبالتالي فإن حصة الأسرة هي QF = R / nbParts = 90,000 / 4 = 22,500 يورو؛
  • ضريبةهما الإجمالية I1 مع أطفال هي I1 = 0.14 × 90,000 – 1,394.96 × 4 = 7,020 يورو؛
  • ضريبة الإجمالي I2 بدون أطفال:
    • QF = 90,000 / 2 = 45,000 يورو؛
    • I2 = 0.3 × 90,000 – 5,798 × 2 = 15,404 يورو؛
    • تنص قاعدة سقف الحصة العائلية على أن المزايا التي يوفرها الأطفال لا يمكن أن تتجاوز (1,551 × 4 نصف حصص) = 6,204 يورو. ومع ذلك، في هذه الحالة، فإن I2 – I1 = 15,404 – 7,020 = 8,384 يورو، وهو مبلغ أكبر من 6,204 يورو؛
    • وبالتالي، يُعاد حساب الضريبة الإجمالية على النحو التالي: I3 = I2 - 6,204 = 15,404 - 6,204 = 9,200 يورو؛

لن يحصل هذا الزوجان على أي خصم ضريبي أو تخفيض، وستكون ضريبتهم النهائية 9,200 يورو.

4.1.7. الأرقام الرسمية

حساب الضريبة أمر معقد. في هذا المستند، ستُجرى اختبارات باستخدام الأمثلة التالية. النتائج مأخوذة من محاكي مصلحة الضرائب [https://www3.impots.gouv.fr/simulateur/calcul_impot/2019/simplifie/index.htm]:

المكلف
النتائج الرسمية
النتائج المستمدة من خوارزمية الوثيقة
زوجان لديهما طفلان ودخلهما السنوي 55,555 يورو
الضريبة = 2,815 يورو
معدل الضريبة = 14%
الضريبة = 2,814 يورو
معدل الضريبة = 14%
زوجان ولديهما طفلان ودخلهما السنوي 50,000 يورو
الضريبة = 1,385 يورو
الائتمان الضريبي = 720 يورو
التخفيض = 0 يورو
معدل الضريبة = 14%
الضريبة = 1,384 يورو
الخصم = 384 يورو
الائتمان = 347 يورو
معدل الضريبة = 14%
زوجان لديهما 3 أطفال ودخل سنوي قدره 50,000 يورو
الضريبة = 0 يورو
الائتمان الضريبي = 384 يورو
التخفيض = 346 يورو
معدل الضريبة = 14%
الضريبة = 0 يورو
الخصم = 720 يورو
التخفيض = 0 يورو
معدل الضريبة = 14%
أعزب ولديه طفلان ودخله السنوي 100,000 يورو
الضريبة = 19,884 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 41%
الضريبة = 19,884 يورو
الرسوم الإضافية = 4,480 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 41%
أعزب ولديه 3 أطفال ودخله السنوي 100,000 يورو
الضريبة = 16,782 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 41%
الضريبة = 16,782 يورو
الرسوم الإضافية = 7,176 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 41%
زوجان ولديهما ثلاثة أطفال ودخلهما السنوي 100,000 يورو
الضريبة = 9,200 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 30%
الضريبة = 9,200 يورو
الرسوم الإضافية = 2,180 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 30%
زوجان لديهما 5 أطفال ودخل سنوي قدره 100,000 يورو
الضريبة = 4,230 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 14%
الضريبة = 4,230 يورو
الخصم = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 14%
أعزب، بدون أطفال، ودخل سنوي قدره 100,000 يورو
الضريبة = 22,986 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 41%
الضريبة = 22,986 يورو
الرسوم الإضافية = 0 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 41%
زوجان ولديهما طفلان ودخلهما السنوي 30,000 يورو
الضريبة = 0 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 0%
الضريبة = 0 يورو
الخصم = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 0%
أعزب، بدون أطفال، ودخل سنوي قدره 200,000 يورو
الضريبة = 64,211 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 45%
الضريبة = 64,210 يورو
الرسوم الإضافية = 7,498 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 45%
زوجان ولديهما 3 أطفال ودخلهما السنوي 200,000 يورو
الضريبة = 42,843 يورو
الائتمان الضريبي = 0 يورو
الخصم = 0 يورو
معدل الضريبة = 41%
الضريبة = 42,842 يورو
الرسوم الإضافية = 17,283 يورو
الخصم = 0 يورو
التخفيض = 0 يورو
معدل الضريبة = 41%

في المثال أعلاه، تشير "الرسوم الإضافية" إلى المبلغ الإضافي الذي يدفعه أصحاب الدخل المرتفع بسبب عاملين:

  • الحد الأقصى للخصم البالغ 10% من الدخل السنوي؛
  • الحد الأقصى للبدل العائلي؛

لم يتسن التحقق من هذا المؤشر لأن أداة المحاكاة الخاصة بالسلطة الضريبية لا توفره.

يمكننا أن نرى أن خوارزمية الوثيقة تحسب المبلغ الضريبي الصحيح في كل مرة، وإن كان ذلك بهامش خطأ قدره 1 يورو. ينشأ هامش الخطأ هذا عن التقريب. يتم تقريب جميع المبالغ النقدية لأعلى إلى أقرب يورو في بعض الحالات ولأسفل إلى أقرب يورو في حالات أخرى. نظرًا لعدم إلمامي بالقواعد الرسمية، تم تقريب المبالغ النقدية في خوارزمية الوثيقة:

  • إلى اليورو الأعلى في حالة الخصومات والتخفيضات؛
  • للأسفل إلى أقرب يورو للرسوم الإضافية والضريبة النهائية؛

في القسم التالي، سيتم إجراء اختبارات للتحقق من صحة النتائج. سيتم إجراؤها باستخدام الأمثلة من الجدول السابق مع هامش خطأ مقبول قدره 1 يورو.

4.2. هيكل دليل البرامج النصية

Image

4.3. الإصدار 1

4.3.1. الخوارزمية

نقدم برنامجًا أوليًا يتضمن ما يلي:

  • البيانات اللازمة لحساب الضريبة مبرمجة بشكل ثابت في البرنامج كمصفوفات وثوابت؛
  • يتم تخزين بيانات دافعي الضرائب (متزوج، أطفال، راتب) في ملف نصي أول [taxpayersdata.txt]؛
  • يتم تخزين نتائج حساب الضريبة (متزوج، أطفال، راتب، ضريبة) في ملف نصي ثانٍ [resultats.txt]؛

النص البرمجي [version-01/main.php] هو كما يلي:


<?php
 
// strict types for function parameters
declare(strict_types=1);
 
// global constants
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);
 
// definition of local constants
$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);
 
// reading data
$data = fopen($DATA, "r");
if (!$data) {
  print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
  exit;
}
 
// open results file
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  exit;
}
 
// use the current line of the data file
while ($ligne = fgets($data, 100)) {
  // remove any end-of-line marker
  $ligne = cutNewLineChar($ligne);
  // we retrieve the 3 fields married:children:salary which form $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // tax calculation
  $result = calculImpot($marié, (int) $enfants, (float) $salaire, $limites, $coeffR, $coeffN);
  // enter the result in the results file
  $result = ["marié" => $marié, "enfants" => $enfants, "salaire" => $salaire] + $result;
  fputs($résultats, \json_encode($result, JSON_UNESCAPED_UNICODE) . "\n");
  // following data
}
// close files
fclose($data);
fclose($résultats);
 
// end
exit;
 
// --------------------------------------------------------------------------
function cutNewLinechar(string $ligne): string {
  // delete the end-of-line mark from $ligne if it exists
  $L = strlen($ligne);  // line length
  while (substr($ligne, $L - 1, 1) === "\n" or substr($ligne, $L - 1, 1) === "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // end
  return($ligne);
}
 
// tAX CALCULATION
// --------------------------------------------------------------------------
function calculImpot(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {

  // result
  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 {

  // result
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}
 
// revenuImposable=annualwage-discount
// the allowance has a minimum and a maximum
function getRevenuImposable(float $salaire): float {

  // result
  return floor($revenuImposable);
}
 
// calculates any discount
function getDecote(string $marié, float $salaire, float $impots): float {

  // result
  return ceil($décôte);
}
 
// calculates any reduction
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {
  /
  // result
  return ceil($réduction);
}

ملف البيانات 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

ملف results.txt (متزوج، أطفال، راتب، ضريبة، رسوم إضافية، خصم، تخفيض، معدل الضريبة) للنتائج التي تم الحصول عليها:

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

تعليقات

  • السطر 4: نطبق الالتزام الصارم بنوع معلمات الدالة؛
  • الأسطر 7–16: تعريف جميع الثوابت اللازمة لحساب الضريبة؛
  • السطر 19: اسم الملف النصي الذي يحتوي على بيانات دافع الضرائب (الحالة الاجتماعية، عدد الأبناء، الراتب)؛
  • السطر 20: اسم الملف النصي الذي يحتوي على نتائج (متزوج، أطفال، راتب، ضريبة) حساب الضريبة؛
  • الأسطر 21–23: مصفوفات البيانات الثلاثة التي تحدد شرائح الضريبة المختلفة لحساب الضريبة؛
  • الأسطر 26–30: فتح ملف بيانات دافع الضرائب للقراءة [r]. تُرجع الدالة [fopen] القيمة المنطقية FALSE إذا تعذر فتح الملف؛
  • الأسطر 33–37: فتح ملف النتائج في وضع الكتابة [w]؛
  • الأسطر 40-51: حلقة لقراءة الأسطر (الزوج، الأبناء، الدخل) من ملف بيانات دافع الضرائب؛
  • السطر 40: تقرأ الدالة [fgets] 100 حرفًا وتتوقف عند أول فاصل أسطر تصادفه. هنا، يقل طول جميع الأسطر عن 100 حرف. إذا تم العثور على فاصل أسطر، يتم تضمينه في السلسلة المرجعة. عند الوصول إلى نهاية الملف، ترجع الدالة [fgets] القيمة FALSE؛
  • السطر 42: تتم إزالة حرف نهاية السطر؛
  • السطر 44: يتم استرداد مكونات السطر (متزوج، أطفال، راتب)؛
  • السطر 46: يتم حساب الضريبة. يتم إرجاع النتيجة كمصفوفة ترابطية (السطر 76)؛
  • السطر 48: تتم إضافة المفاتيح [married، children، salary] إلى المصفوفة التي تم استردادها مسبقًا؛
  • السطر 49: يتم تخزين النتيجة في ملف النتائج كسلسلة JSON؛
  • السطران 53-54: بمجرد الانتهاء من معالجة ملف بيانات دافع الضرائب بالكامل، يتم إغلاق الملفات؛
  • السطر 60: الدالة التي تزيل فاصل الأسطر من السطر $line. فاصل الأسطر هو السلسلة "\r\n" في أنظمة Windows، و"\n" في أنظمة Unix. والنتيجة هي سلسلة الإدخال بدون فاصل الأسطر.
  • السطران 63-64: substr($string, $start, $size) هي السلسلة الفرعية من $string التي تبدأ من الحرف $start وتحتوي على $size حرفًا كحد أقصى؛

وظيفة [calculImpot] هي كما يلي:


// constantes globales
define("PLAFOND_QF_DEMI_PART", 1551);

// calcul de l'impôt
// --------------------------------------------------------------------------
function calculImpot(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {
  // $marié : oui, non
  // $enfants : nombre d'enfants
  // $salaire : salaire annuel
  // $limites, $coeffR, $coeffN : les tableaux des données permettant le calcul de l'impôt
  //
  // calcul de l'impôt avec enfants
  $result1 = calculImpot2($marié, $enfants, $salaire, $limites, $coeffR, $coeffN);
  $impot1 = $result1["impôt"];
  // calcul de l'impôt sans les enfants
  if ($enfants != 0) {
    $result2 = calculImpot2($marié, 0, $salaire, $limites, $coeffR, $coeffN);
    $impot2 = $result2["impôt"];
    // application du plafonnement du quotient familial
    if ($enfants < 3) {
      // $PLAFOND_QF_DEMI_PART euros pour les 2 premiers enfants
      $impot2 = $impot2 - $enfants * PLAFOND_QF_DEMI_PART;
    } else {
      // $PLAFOND_QF_DEMI_PART euros pour les 2 premiers enfants, le double pour les suivants
      $impot2 = $impot2 - 2 * PLAFOND_QF_DEMI_PART - ($enfants - 2) * 2 * PLAFOND_QF_DEMI_PART;
    }
  } else {
    $impot2 = $impot1;
    $result2 = $result1;
  }
  // on prend l'impôt le plus fort avec le taux et la surcôte qui vont avec
  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"];
  }
  // calcul d'une éventuelle décôte
  $décôte = getDecote($marié, $salaire, $impot);
  $impot -= $décôte;
  // calcul d'une éventuelle réduction d'impôts
  $réduction = getRéduction($marié, $salaire, $enfants, $impot);
  $impot -= $réduction;
  // résultat
  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 {

  // résultat
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}
 
// revenuImposable=salaireAnnuel-abattement
// l'abattement de 10 % a un min et un max
function getRevenuImposable(float $salaire): float {

}
 
// calcule une décôte éventuelle
function getDecote(string $marié, float $salaire, float $impots): float {

  // résultat
  return ceil($décôte);
}
 
// calcule une réduction éventuelle
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {

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

تعليقات

  • السطر 10: يتم حساب الضريبة الإجمالية بما في ذلك الأطفال. يتم إرجاع النتيجة في الصيغة ["tax" => $tax, "surcharge" => $surcharge, "rate" => $coeffR[$i]] حيث:
    • [‘tax’]: الضريبة الإجمالية؛
    • [‘surcharge’]: مبلغ الرسوم الإضافية، إن وجدت. ينطبق هذا عندما يتجاوز الخصم بنسبة 10% الحد الأدنى البالغ 12,502 يورو؛
    • [‘rate’]: معدل الضريبة المفروض على دافع الضرائب؛
  • السطر 11: الضريبة الإجمالية المستحقة [impot1]؛
  • السطران 13-14: إذا كان لدى دافع الضرائب طفل واحد على الأقل، يتم إعادة حساب الضريبة باستخدام نفس البيانات ولكن مع 0 أطفال. هذا الحساب الثاني ضروري لتحديد ما إذا كان التخفيض الممنوح للأطفال (nbParts*coeffN) يتجاوز حدًا معينًا؛
  • السطر 15: الضريبة الإجمالية [impot2] المستحقة؛
  • السطور 16-23: بالنسبة للضريبة الإجمالية [impot2]، يتم الآن أخذ الأطفال في الاعتبار: كل حصة نصفية يوفرها الأطفال تسمح بتخفيض قدره [PLAFOND_QF_DEMI_PART] يورو؛
  • السطران 25-26: الحالة التي لا يكون فيها للمكلف أطفال. في هذه الحالة، لا داعي لحساب [impot2]. فهو يساوي [impot1]؛
  • الأسطر 29-37: تم حساب ضريبتين إجماليتين [impot1، impot2]. تحتفظ سلطة الضرائب بأعلىهما. وينتج عن ذلك ضريبة إجمالية [impot]؛
  • السطران 39-40: قد يخضع المبلغ الإجمالي [tax] لتخفيض؛
  • السطران 42-43: قد يخضع المبلغ الإجمالي [impot] لتخفيض؛
  • السطر 45: [tax] هو الآن الضريبة الصافية المستحقة. يتم إرجاع النتائج؛

الدالة [calculImpot2] هي كما يلي:


// --------------------------------------------------------------------------
function calculImpot2(string $marié, int $enfants, float $salaire, array $limites, array $coeffR, array $coeffN): array {
  // $marié : oui, non
  // $enfants : nombre d'enfants
  // $salaire : salaire annuel
  // $limites, $coeffR, $coeffN : les tableaux des données permettant le calcul de l'impôt
  //
  // nombre de parts
  $marié = strtolower($marié);
  if ($marié === "oui") {
    $nbParts = $enfants / 2 + 2;
  } else {
    $nbParts = $enfants / 2 + 1;
  }
  // 1 part par enfant à partir du 3e
  if ($enfants >= 3) {
    // une demi-part de + pour chaque enfant à partir du 3e
    $nbParts += 0.5 * ($enfants - 2);
  }
  // revenu imposable
  $revenuImposable = getRevenuImposable($salaire);
  // surcôte
  $surcôte = floor($revenuImposable - 0.9 * $salaire);
  // pour des pbs d'arrondi
  if ($surcôte < 0) {
    $surcôte = 0;
  }
  // quotient familial
  $quotient = $revenuImposable / $nbParts;
  // est mis à la fin du tableau limites pour arrêter la boucle qui suit
  $limites[count($limites) - 1] = $quotient;
  // calcul de l'impôt
  $i = 0;
  while ($quotient > $limites[$i]) {
    $i++;
  }
  // du fait qu'on a placé $quotient à la fin du tableau $limites, la boucle précédente
  // ne peut déborder du tableau $limites
  // maintenant on peut calculer l'impôt
  $impôt = floor($revenuImposable * $coeffR[$i] - $nbParts * $coeffN[$i]);
  // résultat
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}
 
// revenuImposable=salaireAnnuel-abattement
// l'abattement a un min et un max
function getRevenuImposable(float $salaire): float {
  
  // résultat
  return floor($revenuImposable);
}
 

تعليقات

  • هنا، نطبق حساب الضريبة باستخدام جدول الضريبة التصاعدي؛
  • السطر 9: strtolower($string) يحول $string إلى أحرف صغيرة؛
  • الأسطر 10-19: حساب عدد أسهم دافع الضرائب؛
  • السطر 21: نحسب الدخل الخاضع للضريبة باستخدام دالة. في الواقع، رأينا أنه ليس دائمًا 0.9*AnnualIncome. الحد الأقصى للخصم بنسبة 10% هو في الواقع 12,502 يورو؛
  • السطر 23: يحسب الرسوم الإضافية المحتملة إذا كان الدخل الخاضع للضريبة أكبر من 0.9*الدخل_السنوي؛
  • الأسطر 25-27: تصحيح حقيقة أنه، بسبب أخطاء التقريب، نحصل أحيانًا على [$surcharge=-1]؛
  • السطر 29: حاصل قسمة الأسرة؛
  • الأسطر 30-36: يُستخدم هذا الناتج لتحديد الشريحة الضريبية للمكلف؛
  • السطر 40: بمجرد تحديد الشريحة الضريبية للمكلف، يمكن حساب الضريبة الإجمالية. تعرض الدالة floor($x) العدد الصحيح الأقرب إلى [$x]؛
  • السطر 42: يتم إرجاع المعلومات المحسوبة؛

دالة [getRevenuImposable] هي كما يلي:


// constantes globales
define("ABATTEMENT_DIXPOURCENT_MAX", 12502);
define("ABATTEMENT_DIXPOURCENT_MIN", 437);

// revenuImposable=salaireAnnuel-abattement
// l'abattement a un min et un max
function getRevenuImposable(float $salaire): float {
  // abattement de 10% du salaire
  $abattement = 0.1 * $salaire;
  // cet abattement ne peut dépasser ABATTEMENT_DIXPOURCENT_MAX
  if ($abattement > ABATTEMENT_DIXPOURCENT_MAX) {
    $abattement = ABATTEMENT_DIXPOURCENT_MAX;
  }
  // l'abattement ne peut être inférieur à ABATTEMENT_DIXPOURCENT_MIN
  if ($abattement < ABATTEMENT_DIXPOURCENT_MIN) {
    $abattement = ABATTEMENT_DIXPOURCENT_MIN;
  }
  // revenu imposable
  $revenuImposable = $salaire - $abattement;
  // résultat
  return floor($revenuImposable);
}

تعليقات

  • السطر 5: الخصم القياسي هو 10% من الراتب السنوي؛
  • الأسطر 7-9: لا يمكن أن يتجاوز الخصم الحد الأقصى للخصم [ABATTEMENT_DIXPOURCENT_MAX]؛
  • الأسطر 10-13: لا يمكن أن يقل الخصم عن الحد الأدنى للخصم [ABATTEMENT_DIXPOURCENT_MIN]؛
  • السطر 15: حساب الدخل الخاضع للضريبة؛

وظيفة [getDecote] هي كما يلي:


// constantes globales
define("PLAFOND_DECOTE_CELIBATAIRE", 1196);
define("PLAFOND_DECOTE_COUPLE", 1970);
define("PLAFOND_IMPOT_COUPLE_POUR_DECOTE", 2627);
define("PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE", 1595);

// calcule une décôte éventuelle
function getDecote(string $marié, float $salaire, float $impots): float {
  // au départ, une décôt nulle
  $décôte = 0;
  // montant maximal d'tax to get the discount
  $plafondImpôtPourDécôte = $marié === "oui" ? PLAFOND_IMPOT_COUPLE_POUR_DECOTE : PLAFOND_IMPOT_CELIBATAIRE_POUR_DECOTE;
  if ($impots < $plafondImpôtPourDécôte) {
    // montant maximal de la décôte
    $plafondDécôte = $marié === "oui" ? PLAFOND_DECOTE_COUPLE : PLAFOND_DECOTE_CELIBATAIRE;
    // décôte théorique
    $décôte = $plafondDécôte - 0.75 * $impots;
    // la décôte ne peut dépasser le montant de l'tax
    if ($décôte > $impots) {
      $décôte = $impots;
    }
    // pas de décôte <0
    if ($décôte < 0) {
      $décôte = 0;
    }
  }
  // résultat
  return ceil($décôte);
}

تعليقات

  • السطر 6: الحد الأقصى لمبلغ الضريبة الإجمالي للتأهل للحصول على تخفيض ضريبي. يختلف هذا المبلغ بين الأفراد غير المتزوجين والأزواج؛
  • السطر 7: ما إذا كان دافع الضرائب مؤهلاً للحصول على التخفيض الضريبي؛
  • السطر 11: صيغة الائتمان الضريبي. [taxCreditCap] هو الحد الأقصى لمبلغ الائتمان الضريبي. يتم حساب هذا المبلغ الأقصى في السطر 9. ومرة أخرى، يعتمد ذلك على حالة المكلف بالضريبة — متزوج أو أعزب؛
  • الأسطر 13-15: لا يمكن أن يتجاوز الخصم إجمالي الضريبة المستحقة. وهذا هو الحال، على سبيل المثال، إذا كانت [taxes] تساوي 0 في السطر 11؛
  • السطور 17-19: لتجنب التقريب إلى -1؛

وظيفة [getReduction] هي كما يلي:


// constantes globales
define("PLAFOND_REVENUS_CELIBATAIRE_POUR_REDUCTION", 21037);
define("PLAFOND_REVENUS_COUPLE_POUR_REDUCTION", 42074);
define("VALEUR_REDUC_DEMI_PART", 3797);

// calcule une réduction éventuelle
function getRéduction(string $marié, float $salaire, int $enfants, float $impots): float {
  // le plafond des revenus pour avoir droit à la réduction de 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;
  }
  // revenu imposable
  $revenuImposable = getRevenuImposable($salaire);
  // réduction
  $réduction = 0;
  if ($revenuImposable < $plafondRevenuPourRéduction) {
    // réduction de 20%
    $réduction = 0.2 * $impots;
  }
  // résultat
  return ceil($réduction);
}

تعليقات

  • الأسطر 4-10: لكي تكون مؤهلاً للحصول على تخفيض ضريبي، يجب أن يكون الدخل الخاضع للضريبة (السطر 10) أقل من الحد الأدنى المحسوب في الأسطر 4-8؛
  • الأسطر 13-16: إذا تم استيفاء الشروط، يحق للمكلف بالحصول على تخفيض ضريبي بنسبة 20% (السطر 15)؛

4.3.2. النتائج

ملف البيانات 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

ملف results.txt (متزوج، أطفال، راتب، ضريبة، رسوم إضافية، خصم، تخفيض، معدل الضريبة) للنتائج التي تم الحصول عليها:

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

تتوافق النتائج التي تم الحصول عليها مع تلك التي تم الحصول عليها باستخدام أداة المحاكاة الخاصة بالسلطة الضريبية.

4.3.3. الخلاصة

تعتبر خوارزمية حساب الضريبة معقدة، حتى في الحالات التي تعتبر بسيطة. ولن نعيد تناولها هنا. عبر الإصدارات المختلفة، سيبقى جوهرها كما هو على الرغم من بعض التغييرات في العرض. ولذلك سنعلق فقط على هذا الأخير.

4.4. الإصدار 2

4.4.1. التغييرات

في الإصدار السابق، كانت البيانات المطلوبة لحساب الضريبة مبرمجة بشكل ثابت كثوابت ومصفوفات. يجب تجنب هذه الطريقة. في الإصدار الجديد، يتم نقل هذه البيانات إلى ملف JSON:

Image

محتويات ملف [taxadmindata.json] هي كما يلي:


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

الإصدار الجديد [version-02/main.php] هو كما يلي:


<?php
 
// strict adherence to declared function parameter types
declare (strict_types=1);
 
// definition of constants
$TAXPAYERSDATA = "taxpayersdata.txt";
$RESULTATS = "resultats.txt";
$TAXADMINDATA = "taxadmindata.json";
 
// retrieve the contents of the tax data file
$fileContents = \file_get_contents($TAXADMINDATA);
$erreur = FALSE;
// mistake?
if (!$fileContents) {
  // we note the error
  $erreur = TRUE;
  $message = "Le fichier des données [$TAXADMINDATA] n'existe pas";
}
 
if (!$erreur) {
  // retrieve the jSON code from the configuration file in an associative array
  $taxAdminData = \json_decode($fileContents, true);
  // mistake?
  if (!$taxAdminData) {
    // we note the error
    $erreur = TRUE;
    $message = "Le fichier de données jSON [$TAXADMINDATA] n'a pu être exploité correctement";
  }
}
 
// mistake?
if ($erreur) {
  print "$message\n";
  exit;
}
 
// open results file
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  // output
  exit;
}
 
// opening taxpayer data file
$taxpayersdata = fopen($TAXPAYERSDATA, "r");
if (!$taxpayersdata) {
  print "Impossible d'ouvrir le fichier des contribuables [$TAXPAYERSDATA]\n";
  // output
  exit;
}
 
// use the current line of the data file
while ($ligne = fgets($taxpayersdata, 100)) {
  // remove any end-of-line marker
  $ligne = cutNewLineChar($ligne);
  // we retrieve the 3 fields married:children:salary which form $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // tax calculation
  $result = calculImpot($taxAdminData, $marié, (int) $enfants, (int) $salaire);
  // enter the result in the results file
  $result = ["marié" => $marié, "enfants" => $enfants, "salaire" => $salaire] + $result;
  fputs($résultats, \json_encode($result, JSON_UNESCAPED_UNICODE) . "\n");
  // following data
}
// close files
fclose($taxpayersdata);
fclose($résultats);
 
// end
exit;
 
// --------------------------------------------------------------------------
function cutNewLinechar(string $ligne) {

  // end
  return($ligne);
}
 
// tAX CALCULATION
// --------------------------------------------------------------------------
function calculImpot(array $taxAdminData, string $marié, int $enfants, float $salaire) {
  // $marié : yes, no
  // $enfants : number of children
  // $salaire: annual salary
  // $taxAdminData: tax administration data
  //
  // tax calculation with children
  $result1 = calculImpot2($taxAdminData, $marié, $enfants, $salaire);
  $impot1 = $result1["impôt"];
  // tax calculation without children
  if ($enfants != 0) {
    $result2 = calculImpot2($taxAdminData, $marié, 0, $salaire);
    $impot2 = $result2["impôt"];
    // application of the family allowance ceiling
    if ($enfants < 3) {
      // $PLAFOND_QF_DEMI_PART euros for the first 2 children
      $impot2 = $impot2 - $enfants * $taxAdminData["PLAFOND_QF_DEMI_PART"];
    } else {
      // $PLAFOND_QF_DEMI_PART euros for the first 2 children, double for subsequent children
      $impot2 = $impot2 - 2 * $taxAdminData["PLAFOND_QF_DEMI_PART"] - ($enfants - 2) * 2 * $taxAdminData["PLAFOND_QF_DEMI_PART"];
    }
  } else {
    $impot2 = $impot1;
    $result2 = $result1;
  }
  // we take the highest tax with the rate and surcharge that go with it
  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"];
  }
  // calculation of any discount
  $décôte = getDecote($taxAdminData, $marié, $salaire, $impot);
  $impot -= $décôte;
  // calculation of any tax reduction
  $réduction = getRéduction($taxAdminData, $marié, $salaire, $enfants, $impot);
  $impot -= $réduction;
  // result
  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é : yes, no

  // result
  return ["impôt" => $impôt, "surcôte" => $surcôte, "taux" => $coeffR[$i]];
}
 
// revenuImposable=annualwage-discount
// the allowance has a minimum and a maximum
function getRevenuImposable(array $taxAdminData, float $salaire): float {

  // result
  return floor($revenuImposable);
}
 
// calculates any discount
function getDecote(array $taxAdminData, string $marié, float $salaire, float $impots): float {

  // result
  return ceil($décôte);
}
 
// calculates any reduction
function getRéduction(array $taxAdminData, string $marié, float $salaire, int $enfants, float $impots): float {

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

تعليقات

  • الأسطر 11–19: نحاول قراءة محتويات ملف JSON المسمى [TAXADMINDATA]؛
  • الأسطر 21–30: إذا تمت قراءة ملف JSON بنجاح، يتم فك تشفير محتوياته إلى المصفوفة الترابطية [$taxAdminData]؛
  • الأسطر 32–36: إذا حدث خطأ في أي من العمليتين السابقتين، يتم كتابة رسالة خطأ إلى وحدة التحكم ويتوقف البرنامج؛
  • الفرق عن الإصدار 01 هو أن بيانات إدارة الضرائب (المصفوفات والثوابت) مخزنة هنا في المصفوفة الترابطية [$taxAdminData]، بينما في الإصدار 01، كانت مخزنة في مصفوفات وثوابت عامة. إن الطبيعة العامة لهذه الثوابت هي ما يميز بين الإصدارين:
    • في الإصدار 01، كانت الثوابت معروفة في جميع وظائف [main.php]؛
    • لتحقيق نفس النتيجة في الإصدار 02، يجب تمرير المصفوفة الترابطية [$taxAdminData] كمعلمة إلى جميع الدوال (الأسطر 83، 129، 138، 145، 152)؛
  • يجب أن تستخدم كل دالة في الإصدار 02 محتويات المصفوفة [$taxAdminData]؛
  • الأسطر 83–126: في الدالة [calculateTax]، حيث كانت الثوابت العالمية أو المصفوفات [limits، coeffR، coeffN] تُستخدم سابقًا، نستخدم الآن محتويات المصفوفة [$taxAdminData] التي تم تمريرها كمعلمة (الأسطر 99، 102)؛
  • يتم إعادة كتابة جميع الدوال الأخرى بنفس الطريقة؛

النتائج التي تم الحصول عليها هي نفس تلك التي تم الحصول عليها في الإصدار السابق.

4.4.2. الخلاصة

الإصدار 02 أكثر مرونة بكثير من الإصدار 01. في عام 2020، من المرجح أن تكون خوارزمية حساب الضرائب هي نفسها كما في عام 2019. ولن يتغير سوى شرائح الضرائب وثوابت الحساب. وسيكفي عندئذٍ تحديث ملف [taxadmindata.json]. مع الإصدار 01، يتعين عليك الدخول إلى الكود لتعديل شرائح الضرائب وثوابت الحساب. ومع ذلك، من المرجح أن الأشخاص الذين يحتاجون إلى تغيير قيم شرائح الضرائب وثوابت الحساب لا يملكون حق الوصول إلى كود الخوارزمية.