From 0ae406444b29741b858875d45a1553723529ab5e Mon Sep 17 00:00:00 2001 From: Pablo Ferrandez Roca Date: Fri, 24 Apr 2026 19:01:42 +0200 Subject: [PATCH 1/2] corregido el bug de las casillas 12 - 13 y 28 - 29 --- Lib/Modelo303.php | 33 +++++++++++++++------------ Model/Join/PartidaImpuestoResumen.php | 12 +++++++--- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Lib/Modelo303.php b/Lib/Modelo303.php index f08bfe4..06cd660 100644 --- a/Lib/Modelo303.php +++ b/Lib/Modelo303.php @@ -21,6 +21,7 @@ use FacturaScripts\Core\Base\DataBase; use FacturaScripts\Core\Tools; +use FacturaScripts\Dinamic\Lib\InvoiceOperation; use FacturaScripts\Dinamic\Model\Ejercicio; use FacturaScripts\Dinamic\Model\Join\PartidaImpuestoResumen; @@ -61,8 +62,6 @@ class Modelo303 // Adquisiciones intracomunitarias 'IVARUE' => ['21' => ['base' => '10', 'cuota' => '11']], - // Operaciones con inversión del sujeto pasivo - // TODO: 'xxxxx' => ['21' => ['base' => '12', 'cuota' => '13']], // Recargo de equivalencia 'IVARRE' => [ @@ -154,6 +153,7 @@ public function loadFromResumen(array $resumen): void foreach ($resumen as $item) { $this->addMovimiento( $item->codcuentaesp ?? '', + $item->operacion ?? '', (float) $item->iva, (float) $item->recargo, (float) $item->baseimponible, @@ -182,20 +182,23 @@ public static function treasury(string $codejercicio, string $period): array ]; } - /** - * Add a tax movement to the model (base + quota by type and rate) - * - Determine the correct square based on the type and tax rate. - * - Update the base and quota squares accordingly. - * - * @param string $tipo - * @param float $iva - * @param float $recargo - * @param float $base - * @param float $cuota - * @return void - */ - private function addMovimiento(string $tipo, float $iva, float $recargo, float $base, float $cuota): void + private function addMovimiento(string $tipo, string $operacion, float $iva, float $recargo, float $base, float $cuota): void { + // ISP: inversión del sujeto pasivo (no-UE, servicios intracomunitarios B2B, doméstico art. 84) + // Devengado → casillas 12-13 / deducible → casillas 28-29 + if (in_array($operacion, [InvoiceOperation::REVERSE_CHARGE, InvoiceOperation::INTRA_COMMUNITY_SERVICES])) { + if (in_array($tipo, ['IVAREP', 'IVARUE'])) { + $this->square['12'] += $base; + $this->square['13'] += $cuota; + return; + } + if (in_array($tipo, ['IVASOP', 'IVASUE'])) { + $this->square['28'] += $base; + $this->square['29'] += $cuota; + return; + } + } + if (false === isset($this->casillaMap[$tipo])) { return; } diff --git a/Model/Join/PartidaImpuestoResumen.php b/Model/Join/PartidaImpuestoResumen.php index 7b9a70e..0575b1e 100644 --- a/Model/Join/PartidaImpuestoResumen.php +++ b/Model/Join/PartidaImpuestoResumen.php @@ -1,7 +1,7 @@ + * Copyright (C) 2017-2026 Carlos Garcia Gomez * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -44,6 +44,7 @@ protected function getFields(): array 'codcuentaesp' => 'COALESCE(subcuentas.codcuentaesp, cuentas.codcuentaesp)', 'tipo_desc' => 'cuentasesp.descripcion', + 'operacion' => 'COALESCE(facturasprov.operacion, facturascli.operacion)', 'baseimponible' => $this->sqlForRoundedSum('partidas.baseimponible'), 'debe' => $this->sqlForRoundedSum('partidas.debe'), @@ -65,7 +66,8 @@ protected function getGroupFields(): string . ', partidas.recargo' . ', subcuentas.descripcion' . ', COALESCE(subcuentas.codcuentaesp, cuentas.codcuentaesp)' - . ', cuentasesp.descripcion'; + . ', cuentasesp.descripcion' + . ', COALESCE(facturasprov.operacion, facturascli.operacion)'; } /** @@ -80,7 +82,9 @@ protected function getSQLFrom(): string . ' INNER JOIN subcuentas on subcuentas.idsubcuenta = partidas.idsubcuenta' . ' INNER JOIN cuentas on cuentas.idcuenta = subcuentas.idcuenta' . ' LEFT JOIN cuentasesp on cuentasesp.codcuentaesp = coalesce(subcuentas.codcuentaesp, cuentas.codcuentaesp)' - . ' LEFT JOIN series on series.codserie = partidas.codserie'; + . ' LEFT JOIN series on series.codserie = partidas.codserie' + . ' LEFT JOIN facturasprov on facturasprov.codigo = asientos.documento' + . ' LEFT JOIN facturascli on facturascli.codigo = asientos.documento'; } /** @@ -97,6 +101,8 @@ protected function getTables(): array 'cuentas', 'cuentasesp', 'series', + 'facturasprov', + 'facturascli', ]; } From 5014fe8b7d1fb5be0ed108a96a45b8f8d2c30793 Mon Sep 17 00:00:00 2001 From: Pablo Ferrandez Roca Date: Mon, 27 Apr 2026 14:13:57 +0200 Subject: [PATCH 2/2] arreglado error en los tests --- Model/Join/PartidaImpuestoResumen.php | 4 ++-- Test/main/ComprobarFechaDevengoTest.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Model/Join/PartidaImpuestoResumen.php b/Model/Join/PartidaImpuestoResumen.php index 0575b1e..6fb760c 100644 --- a/Model/Join/PartidaImpuestoResumen.php +++ b/Model/Join/PartidaImpuestoResumen.php @@ -83,8 +83,8 @@ protected function getSQLFrom(): string . ' INNER JOIN cuentas on cuentas.idcuenta = subcuentas.idcuenta' . ' LEFT JOIN cuentasesp on cuentasesp.codcuentaesp = coalesce(subcuentas.codcuentaesp, cuentas.codcuentaesp)' . ' LEFT JOIN series on series.codserie = partidas.codserie' - . ' LEFT JOIN facturasprov on facturasprov.codigo = asientos.documento' - . ' LEFT JOIN facturascli on facturascli.codigo = asientos.documento'; + . ' LEFT JOIN (SELECT codigo, operacion FROM facturasprov) facturasprov on facturasprov.codigo = asientos.documento' + . ' LEFT JOIN (SELECT codigo, operacion FROM facturascli) facturascli on facturascli.codigo = asientos.documento'; } /** diff --git a/Test/main/ComprobarFechaDevengoTest.php b/Test/main/ComprobarFechaDevengoTest.php index a8b4e1e..81a6931 100644 --- a/Test/main/ComprobarFechaDevengoTest.php +++ b/Test/main/ComprobarFechaDevengoTest.php @@ -68,7 +68,7 @@ public function testComprobarFechaDevengo() $partidaImpuestoResumen = new PartidaImpuestoResumen(); $partida = $partidaImpuestoResumen->all([ new DataBaseWhere('COALESCE(subcuentas.codcuentaesp, cuentas.codcuentaesp)', 'IVAREP'), - new DataBaseWhere('fecha', Tools::date()), + new DataBaseWhere('asientos.fecha', Tools::date()), ])[0]; $this->assertEquals($invoiceFechaHoy->totaliva, $partida->cuotaiva); $this->assertEquals($invoiceFechaHoy->totaliva, $partida->haber); @@ -77,7 +77,7 @@ public function testComprobarFechaDevengo() $partidaImpuestoResumen = new PartidaImpuestoResumen(); $partida = $partidaImpuestoResumen->all([ new DataBaseWhere('COALESCE(subcuentas.codcuentaesp, cuentas.codcuentaesp)', 'IVAREP'), - new DataBaseWhere('fecha', Tools::date('-1 month')), + new DataBaseWhere('asientos.fecha', Tools::date('-1 month')), ])[0]; $this->assertEquals($invoiceFechaDevengoAnterior->totaliva, $partida->cuotaiva); $this->assertEquals($invoiceFechaDevengoAnterior->totaliva, $partida->haber); @@ -86,7 +86,7 @@ public function testComprobarFechaDevengo() $partidaImpuestoResumen = new PartidaImpuestoResumen(); $partida = $partidaImpuestoResumen->all([ new DataBaseWhere('COALESCE(subcuentas.codcuentaesp, cuentas.codcuentaesp)', 'IVAREP'), - new DataBaseWhere('fecha', Tools::date('+1 month')), + new DataBaseWhere('asientos.fecha', Tools::date('+1 month')), ])[0]; $this->assertEquals($invoiceFechaDevengoPosterior->totaliva, $partida->cuotaiva); $this->assertEquals($invoiceFechaDevengoPosterior->totaliva, $partida->haber);