Skip to content

6. Ejercicio práctico: IMPOTS con objetos (impots_03)

Retomamos el ejercicio ya estudiado anteriormente (apartados 4.2 y 4.3) para resolverlo con un código PHP que utiliza una clase.


<?php

// definición de una clase Impuestos
class Impôts {

  // atributos: las 3 tablas de datos
  private $limites;
  private $coeffR;
  private $coeffN;
  
  // constructor

  public function __construct($IMPOTS) {
    // $IMPOTS: el nombre del archivo que contiene los datos de las tablas $limites, $coeffR, $coeffN
    // ¿Existe el archivo $IMPOTS?
    if (!file_exists($IMPOTS)) {
      throw new Exception("Le fichier $IMPOTS n'existe pas");
    }//if
    // lectura en bloque del archivo
    $tables = file($IMPOTS);
    if (!$tables) {
      throw new Exception("Erreur lors de l'exploitation du fichier $IMPOTS");
    }//if
    // creación de las 3 tablas: se supone que las líneas son sintácticamente correctas
    $u = new Utilitaires(); // para disponer de funciones de utilidad
    $this->limites = explode(":", $u->cutNewLineChar($tables[0]));
    $this->coeffR = explode(":", $u->cutNewLineChar($tables[1]));
    $this->coeffN = explode(":", $u->cutNewLineChar($tables[2]));
    }

  // --------------------------------------------------------------------------
  public function calculer($marié, $enfants, $salaire) {
    // $marié: sí, no
    // $enfants: número de hijos
    // $salaire: salario anual
    
    // número de partes
    $marié = strtolower($marié);
    if ($marié == "oui")
      $nbParts = $enfants / 2 + 2;
    else
      $nbParts=$enfants / 2 + 1;
    // media participación más si hay al menos 3 hijos
    if ($enfants >= 3)
      $nbParts+=0.5;
    // renta imponible
    $revenuImposable = 0.72 * $salaire;
    //: coeficiente familiar
    $quotient = $revenuImposable / $nbParts;
    // se coloca al final de la tabla de límites para detener el bucle siguiente
    $this->limites[count($this->limites) - 1] = $quotient;
    // cálculo del impuesto
    $i = 0;
    while ($quotient > $this->limites[$i])
      $i++;
    // debido a que se ha colocado $quotient al final de la tabla $limites, el bucle anterior
    // no puede salirse de la tabla $limites
    // ahora podemos calcular el impuesto
    return floor($revenuImposable * $this->coeffR[$i] - $nbParts * $this->coeffN[$i]);
  }

}

// una clase de funciones de utilidad
class Utilitaires {

  public function cutNewLinechar($ligne) {
    // se elimina el marcador de fin de línea de $ligne si existe
    $L = strlen($ligne);  // longitud de línea
    while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
      $ligne = substr($ligne, 0, $L - 1);
      $L--;
    }//while
    // fin
    return($ligne);
  }

}

// prueba -----------------------------------------------------
// definición de constantes
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";
// los datos necesarios para el cálculo del impuesto se han colocado en el archivo IMPOTS
// a razón de una línea por tabla en el formato
// «val1»:«val2»:«val3»,...
// se crea un objeto Impuestos
try {
  $I = new Impôts($IMPOTS);
} catch (Exception $e) {
  print $e->getMessage();
  exit;
}
// se crea un objeto utilidades
$u = new Utilitaires();

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

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

// se procesa la línea actual del archivo de datos
while ($ligne = fgets($data, 100)) {
  // se elimina el posible carácter de fin de línea
  $ligne = $u->cutNewLineChar($ligne);
  // se recuperan los 3 campos «casado», «hijos» y «salario» que forman $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // se calcula el impuesto
  $impôt = $I->calculer($marié, $enfants, $salaire);
  // se introduce el resultado
  fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
  // dato siguiente
}// while
// se cierran los archivos
fclose($data);
fclose($résultats);

// fin
print "Terminé\n";
exit;
?>

El archivo [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

El archivo [data.txt]

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

Resultados: los ya obtenidos en las versiones con tablas y archivos.

El archivo [resultats.txt]

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

Comentarios

  • línea 4: la clase Impuestos. Encapsula datos y métodos que permiten el cálculo del impuesto:
  • datos: líneas 7-9: son las tres tablas de datos que permiten calcular el impuesto. Estas tres tablas son inicializadas por el constructor de la línea 13 a partir de un archivo de texto.
  • métodos: línea 32 – el método calcular permite calcular el impuesto.
  • líneas 17, 22: cuando el constructor no puede crear el objeto Impuestos, lanza una excepción.
  • línea 25: la clase Utilitaires se ha definido para encapsular la función cutNewLineChar.
  • líneas 26-28: inicialización de los tres campos privados de la clase Impuestos
  • línea 32: el método «calculer» de la clase «Impôts» permite calcular el impuesto de un contribuyente.
  • líneas 65-78: la clase Utilitaires
  • líneas 89-94: creación de un objeto Impôts con gestión de posibles excepciones. Esta creación utilizará el archivo de texto $IMPOTS para introducir su contenido en los tres campos privados del objeto Impôts.
  • Líneas 96: creación de un objeto Utilidades para disponer de la función cutNewLineChar.