From a9e5b67959d25754904c0f74062ab56de47855a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20S=C3=A1nchez=20Mart=C3=ADnez?= Date: Tue, 12 May 2026 16:56:56 +0200 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=20justificaci=C3=B3n=20de=20gastos?= =?UTF-8?q?=20en=20Modelo=20130?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://facturascripts.com/roadmap/4079 - Se han agregado nuevos campos en es_ES.json para la justificación de gastos. - Se ha implementado la lógica para calcular el 5% de los gastos justificados en Modelo130.php. - Se ha añadido un nuevo checkbox en Modelo130.html.twig para activar la justificación de gastos. - Se han creado pruebas en Modelo130ControllerTest.php para verificar el cálculo de gastos justificados y su impacto en el monto a deducir. Estos cambios permiten a los usuarios justificar gastos y calcular su impacto en la declaración. --- Controller/Modelo130.php | 13 +++++++- Test/main/Modelo130ControllerTest.php | 46 +++++++++++++++++++++++++++ Translation/es_ES.json | 2 ++ View/Modelo130.html.twig | 22 +++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) diff --git a/Controller/Modelo130.php b/Controller/Modelo130.php index 9ab123a..5f14766 100644 --- a/Controller/Modelo130.php +++ b/Controller/Modelo130.php @@ -50,6 +50,12 @@ class Modelo130 extends Controller /** @var string */ public $activeTab = ''; + /** @var bool */ + public $applyGastosJustificacion = false; + + /** @var float */ + public $gastosJustificacion = 0.0; + /** @var string */ public $codejercicio; @@ -428,9 +434,14 @@ protected function loadResults(): void $this->taxbase = round($this->taxbaseIngresos - $this->taxbaseGastos, 2); + $this->applyGastosJustificacion = '1' === $this->request->request->get('gastosJustificacion', '0'); + if ($this->applyGastosJustificacion && $this->taxbase > 0) { + $this->gastosJustificacion = round($this->taxbase * 0.05, 2); + } + $this->todeduct = (float)$this->request->request->get('todeduct', $this->todeduct); - $this->afterdeduct = round(($this->taxbase * $this->todeduct) / 100, 2); + $this->afterdeduct = round((($this->taxbase - $this->gastosJustificacion) * $this->todeduct) / 100, 2); $this->result = round($this->afterdeduct - $this->taxbaseRetenciones - $this->positivosTrimestres, 2); diff --git a/Test/main/Modelo130ControllerTest.php b/Test/main/Modelo130ControllerTest.php index cbe5e1f..e72e352 100644 --- a/Test/main/Modelo130ControllerTest.php +++ b/Test/main/Modelo130ControllerTest.php @@ -62,6 +62,40 @@ public function testGetSqlValueListQuotesValues(): void $this->assertSame("'6400000000','9999.1'", $controller->sqlValueList(['6400000000', '9999.1'])); } + public function testGastosJustificacionCalculaEl5PorCiento(): void + { + $controller = new Modelo130TestAccess(Modelo130TestAccess::class); + $controller->calcularGastos(10000, 2500, true); + + $this->assertEquals(375.0, $controller->gastosJustificacion); + } + + public function testGastosJustificacionEsCeroSiRendimientoNegativo(): void + { + $controller = new Modelo130TestAccess(Modelo130TestAccess::class); + $controller->calcularGastos(1000, 5000, true); + + $this->assertEquals(0.0, $controller->gastosJustificacion); + } + + public function testGastosJustificacionDesactivadoNoAfectaAfterdeduct(): void + { + $controller = new Modelo130TestAccess(Modelo130TestAccess::class); + $controller->calcularGastos(10000, 2500, false); + + $this->assertEquals(0.0, $controller->gastosJustificacion); + $this->assertEquals(round(7500 * 0.20, 2), $controller->afterdeduct); + } + + public function testAfterdeductSeCalculaSobreBaseReducida(): void + { + $controller = new Modelo130TestAccess(Modelo130TestAccess::class); + $controller->calcularGastos(10000, 2500, true); + + // taxbase = 7500, gastosJustificacion = 375, base = 7125, afterdeduct = 7125 * 20% = 1425 + $this->assertEquals(1425.0, $controller->afterdeduct); + } + protected function tearDown(): void { $this->logErrors(); @@ -84,4 +118,16 @@ public function sqlValueList(array $values): string { return $this->getSqlValueList($values); } + + public function calcularGastos(float $ingresos, float $gastos, bool $apply): void + { + $this->taxbaseIngresos = $ingresos; + $this->taxbaseGastos = $gastos; + $this->taxbase = round($ingresos - $gastos, 2); + $this->applyGastosJustificacion = $apply; + if ($apply && $this->taxbase > 0) { + $this->gastosJustificacion = round($this->taxbase * 0.05, 2); + } + $this->afterdeduct = round((($this->taxbase - $this->gastosJustificacion) * $this->todeduct) / 100, 2); + } } diff --git a/Translation/es_ES.json b/Translation/es_ES.json index 7910578..3868bb4 100644 --- a/Translation/es_ES.json +++ b/Translation/es_ES.json @@ -1,6 +1,8 @@ { "after-deduct": "sobre casilla 04", "deductible-subaccounts": "Cuentas deducibles", + "gastos-justificacion": "Gastos de difícil justificación (5%)", + "gastos-justificacion-limit": "Atención: el importe supera el límite anual de 2.000 €", "model-130": "Modelo 130", "model-130-desc": "Se calcula sumando y acumulando cada trimestre, por ejemplo, si visualizamos el 3º trimestre veremos la suma de los trimestres 1, 2 y 3.", "model-130-p": "El Modelo 130 es una declaración trimestral del impuesto de la renta de las personas físicas (IRPF) en el que se liquida el pago fraccionado de este impuesto, a cuenta de la declaración anual que se realiza el año siguiente.", diff --git a/View/Modelo130.html.twig b/View/Modelo130.html.twig index a1fb4db..8ec1328 100644 --- a/View/Modelo130.html.twig +++ b/View/Modelo130.html.twig @@ -142,6 +142,28 @@ +
+
+
+ + +
+
+ +
+ {% if fsc.gastosJustificacion > 2000 %} +

+ {{ trans('gastos-justificacion-limit') }} +

+ {% endif %} +
+
{{ trans('pct-to-deduct') }}