From 7c877a412236175fbc758e113b1a2760cee5c824 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 4 Jun 2025 20:34:18 +0200 Subject: [PATCH 1/3] implementar intracomunitarias --- Controller/EditRegularizacionImpuesto.php | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Controller/EditRegularizacionImpuesto.php b/Controller/EditRegularizacionImpuesto.php index 5f21acd..7000fa5 100644 --- a/Controller/EditRegularizacionImpuesto.php +++ b/Controller/EditRegularizacionImpuesto.php @@ -19,6 +19,7 @@ namespace FacturaScripts\Plugins\Modelo303\Controller; +use FacturaScripts\Core\Base\DataBase; use FacturaScripts\Core\Base\DataBase\DataBaseWhere; use FacturaScripts\Core\DataSrc\Impuestos; use FacturaScripts\Core\DataSrc\Series; @@ -366,6 +367,33 @@ protected function getListPartidaImpuestoResumen(BaseView $view): void // Resultado régimen general $this->modelo303['46'] = $this->modelo303['27'] - $this->modelo303['45']; + + // Información adicional + // Ventas intracomunitarias + $dataBase = new DataBase(); + + $sql = "SELECT SUM(neto) AS neto FROM facturascli "; + $sql .= "WHERE codejercicio = '".$this->getModel()->codejercicio."' AND "; + $sql .= "COALESCE(fechadevengo, fecha) >= ".$dataBase->var2str($this->getModel()->fechainicio)." AND "; + $sql .= "COALESCE(fechadevengo, fecha) < ".$dataBase->var2str($this->getModel()->fechafin)." AND "; + $sql .= "operacion = 'intracomunitaria'"; + $netoFacturasVentasIntra = $dataBase->select($sql)[0]['neto']; + + $this->modelo303['59'] = $netoFacturasVentasIntra; + + // Compras intracomunitarias + $sql = "SELECT SUM(neto) AS base, SUM(totaliva) AS cuota FROM facturasprov "; + $sql .= "WHERE codejercicio = '".$this->getModel()->codejercicio."' AND "; + $sql .= "COALESCE(fechadevengo, fecha) >= ".$dataBase->var2str($this->getModel()->fechainicio)." AND "; + $sql .= "COALESCE(fechadevengo, fecha) < ".$dataBase->var2str($this->getModel()->fechafin)." AND "; + $sql .= "operacion = 'intracomunitaria'"; + $result = $dataBase->select($sql)[0]; + + $baseFacturasComprasIntra = $result['base']; + $cuotaFacturasComprasIntra = $result['cuota']; + + $this->modelo303['10'] = $baseFacturasComprasIntra; + $this->modelo303['11'] = $cuotaFacturasComprasIntra; } /** From 3c85a1340bd9e59c07fce4a85521d87b3ff8211e Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 5 Jun 2025 00:14:32 +0200 Subject: [PATCH 2/3] refactor implementar Modelo303Data --- Controller/EditRegularizacionImpuesto.php | 79 ++++++++----------- Lib/Modelo303Data.php | 53 +++++++++++++ View/Modelo303.html.twig | 95 ++++++++++++----------- 3 files changed, 134 insertions(+), 93 deletions(-) create mode 100644 Lib/Modelo303Data.php diff --git a/Controller/EditRegularizacionImpuesto.php b/Controller/EditRegularizacionImpuesto.php index 7000fa5..7592ed4 100644 --- a/Controller/EditRegularizacionImpuesto.php +++ b/Controller/EditRegularizacionImpuesto.php @@ -32,6 +32,7 @@ use FacturaScripts\Dinamic\Model\Join\PartidaImpuestoResumen; use FacturaScripts\Dinamic\Model\Partida; use FacturaScripts\Dinamic\Model\RegularizacionImpuesto; +use FacturaScripts\Plugins\Modelo303\Lib\Modelo303Data; /** * Controller to list the items in the RegularizacionImpuesto model @@ -51,8 +52,7 @@ class EditRegularizacionImpuesto extends EditController /** @var float */ public $total; - /** @var array */ - public array $modelo303 = []; + public Modelo303Data $modelo303; public function getModelClassName(): string { @@ -247,21 +247,6 @@ protected function getListPartidaImpuestoResumen(BaseView $view): void $partidasAgrupadas[$partida->codsubcuenta][] = $partida; } - // inicializamos el modelo303 - $this->modelo303 = []; - for ($i = 0; $i <= 200; $i++) { - $this->modelo303[sprintf('%02d', $i)] = 0.00; - } - - // set default values - $this->modelo303['02'] = 4.00; - $this->modelo303['05'] = 10.00; - $this->modelo303['08'] = 21.00; - $this->modelo303['157'] = 1.75; - $this->modelo303['169'] = 0.5; - $this->modelo303['20'] = 1.4; - $this->modelo303['23'] = 5.2; - // obtenemos los códigos de subcuentas agrupados según tipo iva // esto lo hacemos por si existen varios impuestos // del mismo iva y distintas subcuentas @@ -280,93 +265,95 @@ protected function getListPartidaImpuestoResumen(BaseView $view): void $subcuentasSegunRecargo[$impuesto->recargo]['soportado'][] = $impuesto->codsubcuentasopre; } + // Iniciamos modelo 303 + $this->modelo303 = new Modelo303Data(); + foreach ($partidasAgrupadas as $subcuenta => $movimientos) { foreach ($movimientos as $mov) { // IVA 4% if (in_array($subcuenta, $subcuentasSegunIVA[4]['repercutido'])) { - $this->modelo303['01'] += $mov->baseimponible; - $this->modelo303['03'] += $mov->haber; + $this->modelo303->add('01', $mov->baseimponible); + $this->modelo303->add('03', $mov->haber); } // IVA 10% if (in_array($subcuenta, $subcuentasSegunIVA[10]['repercutido'])) { - $this->modelo303['04'] += $mov->baseimponible; - $this->modelo303['06'] += $mov->haber; + $this->modelo303->add('04', $mov->baseimponible); + $this->modelo303->add('06', $mov->haber); } // IVA 21% if (in_array($subcuenta, $subcuentasSegunIVA[21]['repercutido'])) { - $this->modelo303['07'] += $mov->baseimponible; - $this->modelo303['09'] += $mov->haber; + $this->modelo303->add('07', $mov->baseimponible); + $this->modelo303->add('09', $mov->haber); } // IVA 0% if (in_array($subcuenta, $subcuentasSegunIVA[0]['repercutido'])) { - $this->modelo303['150'] += $mov->baseimponible; - $this->modelo303['152'] += $mov->haber; + $this->modelo303->add('150', $mov->baseimponible); + $this->modelo303->add('152', $mov->haber); } // RECARGO 1.75% if (in_array($subcuenta, $subcuentasSegunRecargo[1.75]['repercutido'])) { - $this->modelo303['156'] += $mov->baseimponible; - $this->modelo303['158'] += $mov->haber; + $this->modelo303->add('156', $mov->baseimponible); + $this->modelo303->add('158', $mov->haber); } // RECARGO 0.5% if (in_array($subcuenta, $subcuentasSegunRecargo[0.5]['repercutido'])) { - $this->modelo303['168'] += $mov->baseimponible; - $this->modelo303['170'] += $mov->haber; + $this->modelo303->add('168', $mov->baseimponible); + $this->modelo303->add('170', $mov->haber); } // RECARGO 1.4% if (in_array($subcuenta, $subcuentasSegunRecargo[1.4]['repercutido'])) { - $this->modelo303['19'] += $mov->baseimponible; - $this->modelo303['21'] += $mov->haber; + $this->modelo303->add('19', $mov->baseimponible); + $this->modelo303->add('21', $mov->haber); } // RECARGO 5.2% if (in_array($subcuenta, $subcuentasSegunRecargo[5.2]['repercutido'])) { - $this->modelo303['22'] += $mov->baseimponible; - $this->modelo303['24'] += $mov->haber; + $this->modelo303->add('22', $mov->baseimponible); + $this->modelo303->add('24', $mov->haber); } } } // Total cuota devengada - $this->modelo303['27'] = $this->modelo303['152'] + $this->modelo303['167'] + $this->modelo303['03'] + $this->modelo303['155'] + $this->modelo303['06'] + $this->modelo303['09'] + $this->modelo303['11'] + $this->modelo303['13'] + $this->modelo303['15'] + $this->modelo303['158'] + $this->modelo303['170'] + $this->modelo303['18'] + $this->modelo303['21'] + $this->modelo303['24'] + $this->modelo303['26']; + $this->modelo303->set('27', $this->modelo303->get('152') + $this->modelo303->get('167') + $this->modelo303->get('03') + $this->modelo303->get('155') + $this->modelo303->get('06') + $this->modelo303->get('09') + $this->modelo303->get('11') + $this->modelo303->get('13') + $this->modelo303->get('15') + $this->modelo303->get('158') + $this->modelo303->get('170') + $this->modelo303->get('18') + $this->modelo303->get('21') + $this->modelo303->get('24') + $this->modelo303->get('26')); /** * IVA DEDUCIBLE */ - // Por cuotas soportadas en operaciones interiores corrientes foreach ($partidasAgrupadas as $subcuenta => $movimientos) { foreach ($movimientos as $mov) { // IVA 4% if (in_array($subcuenta, $subcuentasSegunIVA[4]['soportado'])) { - $this->modelo303['28'] += $mov->baseimponible; - $this->modelo303['29'] += $mov->debe; + $this->modelo303->add('28', $mov->baseimponible); + $this->modelo303->add('29', $mov->debe); } // IVA 10% if (in_array($subcuenta, $subcuentasSegunIVA[10]['soportado'])) { - $this->modelo303['28'] += $mov->baseimponible; - $this->modelo303['29'] += $mov->debe; + $this->modelo303->add('28', $mov->baseimponible); + $this->modelo303->add('29', $mov->debe); } // IVA 21% if (in_array($subcuenta, $subcuentasSegunIVA[21]['soportado'])) { - $this->modelo303['28'] += $mov->baseimponible; - $this->modelo303['29'] += $mov->debe; + $this->modelo303->add('28', $mov->baseimponible); + $this->modelo303->add('29', $mov->debe); } } } // Total a deducir - $this->modelo303['45'] = $this->modelo303['29'] + $this->modelo303['31'] + $this->modelo303['33'] + $this->modelo303['35'] + $this->modelo303['37'] + $this->modelo303['39'] + $this->modelo303['41'] + $this->modelo303['42'] + $this->modelo303['43'] + $this->modelo303['44']; + $this->modelo303->set('45', $this->modelo303->get('29') + $this->modelo303->get('31') + $this->modelo303->get('33') + $this->modelo303->get('35') + $this->modelo303->get('37') + $this->modelo303->get('39') + $this->modelo303->get('41') + $this->modelo303->get('42') + $this->modelo303->get('43') + $this->modelo303->get('44')); // Resultado régimen general - $this->modelo303['46'] = $this->modelo303['27'] - $this->modelo303['45']; + $this->modelo303->set('46', $this->modelo303->get('27') - $this->modelo303->get('45')); // Información adicional // Ventas intracomunitarias @@ -379,7 +366,7 @@ protected function getListPartidaImpuestoResumen(BaseView $view): void $sql .= "operacion = 'intracomunitaria'"; $netoFacturasVentasIntra = $dataBase->select($sql)[0]['neto']; - $this->modelo303['59'] = $netoFacturasVentasIntra; + $this->modelo303->set('59', $netoFacturasVentasIntra); // Compras intracomunitarias $sql = "SELECT SUM(neto) AS base, SUM(totaliva) AS cuota FROM facturasprov "; @@ -392,8 +379,8 @@ protected function getListPartidaImpuestoResumen(BaseView $view): void $baseFacturasComprasIntra = $result['base']; $cuotaFacturasComprasIntra = $result['cuota']; - $this->modelo303['10'] = $baseFacturasComprasIntra; - $this->modelo303['11'] = $cuotaFacturasComprasIntra; + $this->modelo303->set('10', $baseFacturasComprasIntra); + $this->modelo303->set('11', $cuotaFacturasComprasIntra); } /** diff --git a/Lib/Modelo303Data.php b/Lib/Modelo303Data.php new file mode 100644 index 0000000..04cb9ab --- /dev/null +++ b/Lib/Modelo303Data.php @@ -0,0 +1,53 @@ + 4.00, + '05' => 10.00, + '08' => 21.00, + '157' => 1.75, + '169' => 0.5, + '20' => 1.4, + '23' => 5.2 + ]; + + public function __construct() + { + $this->initialize(); + } + + private function initialize(): void + { + for ($i = 0; $i <= 200; $i++) { + $this->data[sprintf('%02d', $i)] = 0.00; + } + + foreach (self::DEFAULT_RATES as $key => $rate) { + $this->data[$key] = $rate; + } + } + + public function get(string $key): float + { + return $this->data[$key] ?? 0.00; + } + + public function set(string $key, float $value): void + { + $this->data[$key] = $value; + } + + public function add(string $key, float $value): void + { + $this->data[$key] = ($this->data[$key] ?? 0.00) + $value; + } + + public function toArray(): array + { + return $this->data; + } +} diff --git a/View/Modelo303.html.twig b/View/Modelo303.html.twig index 7ea7a34..ac61555 100644 --- a/View/Modelo303.html.twig +++ b/View/Modelo303.html.twig @@ -1,3 +1,4 @@ +{% set modelo303 = fsc.modelo303.toArray() %}
@@ -19,178 +20,178 @@ 150 - {{ fsc.modelo303['150'] is empty ? '' : number(fsc.modelo303['150'], 2) }} + {{ modelo303['150'] }} 151 - {{ fsc.modelo303['151'] is empty ? '' : number(fsc.modelo303['151'], 2) }} + {{ modelo303['151'] }} 152 - {{ fsc.modelo303['152'] is empty ? '' : number(fsc.modelo303['152'], 2) }} + {{ modelo303['152'] }} 165 - {{ fsc.modelo303['165'] is empty ? '' : number(fsc.modelo303['165'], 2) }} + {{ modelo303['165'] }} 166 - {{ fsc.modelo303['166'] is empty ? '' : number(fsc.modelo303['166'], 2) }} + {{ modelo303['166'] }} 167 - {{ fsc.modelo303['167'] is empty ? '' : number(fsc.modelo303['167'], 2) }} + {{ modelo303['167'] }} 01 - {{ fsc.modelo303['01'] is empty ? '' : number(fsc.modelo303['01'], 2) }} + {{ modelo303['01'] }} 02 - {{ fsc.modelo303['02'] is empty ? '' : number(fsc.modelo303['02'], 2) }} + {{ modelo303['02'] }} 03 - {{ fsc.modelo303['03'] is empty ? '' : number(fsc.modelo303['03'], 2) }} + {{ modelo303['03'] }} 153 - {{ fsc.modelo303['153'] is empty ? '' : number(fsc.modelo303['153'], 2) }} + {{ modelo303['153'] }} 154 - {{ fsc.modelo303['154'] is empty ? '' : number(fsc.modelo303['154'], 2) }} + {{ modelo303['154'] }} 155 - {{ fsc.modelo303['155'] is empty ? '' : number(fsc.modelo303['155'], 2) }} + {{ modelo303['155'] }} 04 - {{ fsc.modelo303['04'] is empty ? '' : number(fsc.modelo303['04'], 2) }} + {{ modelo303['04'] }} 05 - {{ fsc.modelo303['05'] is empty ? '' : number(fsc.modelo303['05'], 2) }} + {{ modelo303['05'] }} 06 - {{ fsc.modelo303['06'] is empty ? '' : number(fsc.modelo303['06'], 2) }} + {{ modelo303['06'] }} 07 - {{ fsc.modelo303['07'] is empty ? '' : number(fsc.modelo303['07'], 2) }} + {{ modelo303['07'] }} 08 - {{ fsc.modelo303['08'] is empty ? '' : number(fsc.modelo303['08'], 2) }} + {{ modelo303['08'] }} 09 - {{ fsc.modelo303['09'] is empty ? '' : number(fsc.modelo303['09'], 2) }} + {{ modelo303['09'] }} 10 - {{ fsc.modelo303['10'] is empty ? '' : number(fsc.modelo303['10'], 2) }} + {{ modelo303['10'] }} 11 - {{ fsc.modelo303['11'] is empty ? '' : number(fsc.modelo303['11'], 2) }} + {{ modelo303['11'] }} 12 - {{ fsc.modelo303['12'] is empty ? '' : number(fsc.modelo303['12'], 2) }} + {{ modelo303['12'] }} 13 - {{ fsc.modelo303['13'] is empty ? '' : number(fsc.modelo303['13'], 2) }} + {{ modelo303['13'] }} 14 - {{ fsc.modelo303['14'] is empty ? '' : number(fsc.modelo303['14'], 2) }} + {{ modelo303['14'] }} 15 - {{ fsc.modelo303['15'] is empty ? '' : number(fsc.modelo303['15'], 2) }} + {{ modelo303['15'] }} 156 - {{ fsc.modelo303['156'] is empty ? '' : number(fsc.modelo303['156'], 2) }} + {{ modelo303['156'] }} 157 - {{ fsc.modelo303['157'] is empty ? '' : number(fsc.modelo303['157'], 2) }} + {{ modelo303['157'] }} 158 - {{ fsc.modelo303['158'] is empty ? '' : number(fsc.modelo303['158'], 2) }} + {{ modelo303['158'] }} 168 - {{ fsc.modelo303['168'] is empty ? '' : number(fsc.modelo303['168'], 2) }} + {{ modelo303['168'] }} 169 - {{ fsc.modelo303['169'] is empty ? '' : number(fsc.modelo303['169'], 2) }} + {{ modelo303['169'] }} 170 - {{ fsc.modelo303['170'] is empty ? '' : number(fsc.modelo303['170'], 2) }} + {{ modelo303['170'] }} 16 - {{ fsc.modelo303['16'] is empty ? '' : number(fsc.modelo303['16'], 2) }} + {{ modelo303['16'] }} 17 - {{ fsc.modelo303['17'] is empty ? '' : number(fsc.modelo303['17'], 2) }} + {{ modelo303['17'] }} 18 - {{ fsc.modelo303['18'] is empty ? '' : number(fsc.modelo303['18'], 2) }} + {{ modelo303['18'] }} 19 - {{ fsc.modelo303['19'] is empty ? '' : number(fsc.modelo303['19'], 2) }} + {{ modelo303['19'] }} 20 - {{ fsc.modelo303['20'] is empty ? '' : number(fsc.modelo303['20'], 2) }} + {{ modelo303['20'] }} 21 - {{ fsc.modelo303['21'] is empty ? '' : number(fsc.modelo303['21'], 2) }} + {{ modelo303['21'] }} 22 - {{ fsc.modelo303['22'] is empty ? '' : number(fsc.modelo303['22'], 2) }} + {{ modelo303['22'] }} 23 - {{ fsc.modelo303['23'] is empty ? '' : number(fsc.modelo303['23'], 2) }} + {{ modelo303['23'] }} 24 - {{ fsc.modelo303['24'] is empty ? '' : number(fsc.modelo303['24'], 2) }} + {{ modelo303['24'] }} 25 - {{ fsc.modelo303['25'] is empty ? '' : number(fsc.modelo303['25'], 2) }} + {{ modelo303['25'] }} 26 - {{ fsc.modelo303['26'] is empty ? '' : number(fsc.modelo303['26'], 2) }} + {{ modelo303['26'] }} @@ -201,7 +202,7 @@ {{ trans('total-accrued-fee') }} 27 - {{ fsc.modelo303['27'] is empty ? '' : number(fsc.modelo303['27'], 2) }} + {{ modelo303['27'] }} @@ -228,11 +229,11 @@ {{ trans('deductible-vat-28') }} 28 - {{ fsc.modelo303['28'] is empty ? '' : number(fsc.modelo303['28'], 2) }} + {{ modelo303['28'] }} 29 - {{ fsc.modelo303['29'] is empty ? '' : number(fsc.modelo303['29'], 2) }} + {{ modelo303['29'] }} @@ -243,7 +244,7 @@ {{ trans('total-to-deduct') }} 45 - {{ fsc.modelo303['45'] is empty ? '' : number(fsc.modelo303['45'], 2) }} + {{ modelo303['45'] }} @@ -259,11 +260,11 @@ {{ trans('total-result-of-the-general-regime') }} 46 - {{ fsc.modelo303['46'] is empty ? '' : number(fsc.modelo303['46'], 2) }} + {{ modelo303['46'] }}
-
+ \ No newline at end of file From a7d1c86c3a54ef748e9ac965cfdf324af10f4620 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 5 Jun 2025 01:15:13 +0200 Subject: [PATCH 3/3] refactor implementar Modelo303Calculator --- Controller/EditRegularizacionImpuesto.php | 183 ++------------------ Lib/AccountingItems.php | 51 ++++++ Lib/Modelo303Calculator.php | 199 ++++++++++++++++++++++ 3 files changed, 261 insertions(+), 172 deletions(-) create mode 100644 Lib/AccountingItems.php create mode 100644 Lib/Modelo303Calculator.php diff --git a/Controller/EditRegularizacionImpuesto.php b/Controller/EditRegularizacionImpuesto.php index 7592ed4..317d376 100644 --- a/Controller/EditRegularizacionImpuesto.php +++ b/Controller/EditRegularizacionImpuesto.php @@ -19,19 +19,18 @@ namespace FacturaScripts\Plugins\Modelo303\Controller; -use FacturaScripts\Core\Base\DataBase; use FacturaScripts\Core\Base\DataBase\DataBaseWhere; use FacturaScripts\Core\DataSrc\Impuestos; use FacturaScripts\Core\DataSrc\Series; +use FacturaScripts\Core\KernelException; use FacturaScripts\Core\Lib\ExtendedController\BaseView; use FacturaScripts\Core\Lib\ExtendedController\EditController; -use FacturaScripts\Core\Model\Asiento; use FacturaScripts\Core\Tools; use FacturaScripts\Dinamic\Lib\Accounting\VatRegularizationToAccounting; use FacturaScripts\Dinamic\Lib\SubAccountTools; use FacturaScripts\Dinamic\Model\Join\PartidaImpuestoResumen; -use FacturaScripts\Dinamic\Model\Partida; use FacturaScripts\Dinamic\Model\RegularizacionImpuesto; +use FacturaScripts\Plugins\Modelo303\Lib\Modelo303Calculator; use FacturaScripts\Plugins\Modelo303\Lib\Modelo303Data; /** @@ -210,177 +209,17 @@ protected function getListPartidaImpuesto(BaseView $view, int $group): void } } + /** + * @throws KernelException + */ protected function getListPartidaImpuestoResumen(BaseView $view): void { - $impuestos = Impuestos::all(); - - // obtenemos los codigos de subcuentas de los impuestos - $subcuentas = array_values(array_unique(array_filter(array_merge( - array_column($impuestos, 'codsubcuentarep'), - array_column($impuestos, 'codsubcuentasop'), - )))); - - // Obtenemos los asientos para poder filtrar - // por fecha. Asi nos aseguramos que se filtra - // primero por fecha de devengo y si no existe - // por fecha de factura - $asientos = Asiento::all([ - new DataBaseWhere('codejercicio', $this->getModel()->codejercicio), - new DataBaseWhere('fecha', $this->getModel()->fechainicio, '>='), - new DataBaseWhere('fecha', $this->getModel()->fechafin, '<'), - ], [], 0, 0); - $idsAsientos = array_unique(array_column($asientos, Asiento::primaryColumn())); - - if(empty($idsAsientos)) { - Tools::log()->warning('accounting-entry-not-found'); - return; - } - - $partidas = Partida::all([ - new DataBaseWhere('idasiento', $idsAsientos, 'IN'), - new DataBaseWhere('codsubcuenta', $subcuentas, 'IN') - ], [], 0, 0); - - // agrupamos por subcuenta - $partidasAgrupadas = []; - foreach ($partidas as $partida) { - $partidasAgrupadas[$partida->codsubcuenta][] = $partida; - } - - // obtenemos los códigos de subcuentas agrupados según tipo iva - // esto lo hacemos por si existen varios impuestos - // del mismo iva y distintas subcuentas - $subcuentasSegunIVA = []; - foreach ($impuestos as $impuesto) { - $subcuentasSegunIVA[$impuesto->iva]['repercutido'][] = $impuesto->codsubcuentarep; - $subcuentasSegunIVA[$impuesto->iva]['soportado'][] = $impuesto->codsubcuentasop; - } - - // obtenemos los codigos de subcuentas agrupados según tipo recargo - // esto lo hacemos por si existen varios impuestos - // del mismo recargo y distintas subcuentas - $subcuentasSegunRecargo = []; - foreach ($impuestos as $impuesto) { - $subcuentasSegunRecargo[$impuesto->recargo]['repercutido'][] = $impuesto->codsubcuentarepre; - $subcuentasSegunRecargo[$impuesto->recargo]['soportado'][] = $impuesto->codsubcuentasopre; - } - - // Iniciamos modelo 303 - $this->modelo303 = new Modelo303Data(); - - foreach ($partidasAgrupadas as $subcuenta => $movimientos) { - foreach ($movimientos as $mov) { - // IVA 4% - if (in_array($subcuenta, $subcuentasSegunIVA[4]['repercutido'])) { - $this->modelo303->add('01', $mov->baseimponible); - $this->modelo303->add('03', $mov->haber); - } - - // IVA 10% - if (in_array($subcuenta, $subcuentasSegunIVA[10]['repercutido'])) { - $this->modelo303->add('04', $mov->baseimponible); - $this->modelo303->add('06', $mov->haber); - } - - // IVA 21% - if (in_array($subcuenta, $subcuentasSegunIVA[21]['repercutido'])) { - $this->modelo303->add('07', $mov->baseimponible); - $this->modelo303->add('09', $mov->haber); - } - - // IVA 0% - if (in_array($subcuenta, $subcuentasSegunIVA[0]['repercutido'])) { - $this->modelo303->add('150', $mov->baseimponible); - $this->modelo303->add('152', $mov->haber); - } - - // RECARGO 1.75% - if (in_array($subcuenta, $subcuentasSegunRecargo[1.75]['repercutido'])) { - $this->modelo303->add('156', $mov->baseimponible); - $this->modelo303->add('158', $mov->haber); - } - - // RECARGO 0.5% - if (in_array($subcuenta, $subcuentasSegunRecargo[0.5]['repercutido'])) { - $this->modelo303->add('168', $mov->baseimponible); - $this->modelo303->add('170', $mov->haber); - } - - // RECARGO 1.4% - if (in_array($subcuenta, $subcuentasSegunRecargo[1.4]['repercutido'])) { - $this->modelo303->add('19', $mov->baseimponible); - $this->modelo303->add('21', $mov->haber); - } - - // RECARGO 5.2% - if (in_array($subcuenta, $subcuentasSegunRecargo[5.2]['repercutido'])) { - $this->modelo303->add('22', $mov->baseimponible); - $this->modelo303->add('24', $mov->haber); - } - } - } - - // Total cuota devengada - $this->modelo303->set('27', $this->modelo303->get('152') + $this->modelo303->get('167') + $this->modelo303->get('03') + $this->modelo303->get('155') + $this->modelo303->get('06') + $this->modelo303->get('09') + $this->modelo303->get('11') + $this->modelo303->get('13') + $this->modelo303->get('15') + $this->modelo303->get('158') + $this->modelo303->get('170') + $this->modelo303->get('18') + $this->modelo303->get('21') + $this->modelo303->get('24') + $this->modelo303->get('26')); - - /** - * IVA DEDUCIBLE - */ - // Por cuotas soportadas en operaciones interiores corrientes - foreach ($partidasAgrupadas as $subcuenta => $movimientos) { - foreach ($movimientos as $mov) { - // IVA 4% - if (in_array($subcuenta, $subcuentasSegunIVA[4]['soportado'])) { - $this->modelo303->add('28', $mov->baseimponible); - $this->modelo303->add('29', $mov->debe); - } - - // IVA 10% - if (in_array($subcuenta, $subcuentasSegunIVA[10]['soportado'])) { - $this->modelo303->add('28', $mov->baseimponible); - $this->modelo303->add('29', $mov->debe); - } - - // IVA 21% - if (in_array($subcuenta, $subcuentasSegunIVA[21]['soportado'])) { - $this->modelo303->add('28', $mov->baseimponible); - $this->modelo303->add('29', $mov->debe); - } - } - } - - // Total a deducir - $this->modelo303->set('45', $this->modelo303->get('29') + $this->modelo303->get('31') + $this->modelo303->get('33') + $this->modelo303->get('35') + $this->modelo303->get('37') + $this->modelo303->get('39') + $this->modelo303->get('41') + $this->modelo303->get('42') + $this->modelo303->get('43') + $this->modelo303->get('44')); - - // Resultado régimen general - $this->modelo303->set('46', $this->modelo303->get('27') - $this->modelo303->get('45')); - - // Información adicional - // Ventas intracomunitarias - $dataBase = new DataBase(); - - $sql = "SELECT SUM(neto) AS neto FROM facturascli "; - $sql .= "WHERE codejercicio = '".$this->getModel()->codejercicio."' AND "; - $sql .= "COALESCE(fechadevengo, fecha) >= ".$dataBase->var2str($this->getModel()->fechainicio)." AND "; - $sql .= "COALESCE(fechadevengo, fecha) < ".$dataBase->var2str($this->getModel()->fechafin)." AND "; - $sql .= "operacion = 'intracomunitaria'"; - $netoFacturasVentasIntra = $dataBase->select($sql)[0]['neto']; - - $this->modelo303->set('59', $netoFacturasVentasIntra); - - // Compras intracomunitarias - $sql = "SELECT SUM(neto) AS base, SUM(totaliva) AS cuota FROM facturasprov "; - $sql .= "WHERE codejercicio = '".$this->getModel()->codejercicio."' AND "; - $sql .= "COALESCE(fechadevengo, fecha) >= ".$dataBase->var2str($this->getModel()->fechainicio)." AND "; - $sql .= "COALESCE(fechadevengo, fecha) < ".$dataBase->var2str($this->getModel()->fechafin)." AND "; - $sql .= "operacion = 'intracomunitaria'"; - $result = $dataBase->select($sql)[0]; - - $baseFacturasComprasIntra = $result['base']; - $cuotaFacturasComprasIntra = $result['cuota']; - - $this->modelo303->set('10', $baseFacturasComprasIntra); - $this->modelo303->set('11', $cuotaFacturasComprasIntra); + // Calculamos casillas del modelo 303 + $this->modelo303 = Modelo303Calculator::calculate( + $this->getModel()->codejercicio, + $this->getModel()->fechainicio, + $this->getModel()->fechafin, + ); } /** diff --git a/Lib/AccountingItems.php b/Lib/AccountingItems.php new file mode 100644 index 0000000..dafd1a2 --- /dev/null +++ b/Lib/AccountingItems.php @@ -0,0 +1,51 @@ +='), + new DataBaseWhere('fecha', $fechafin, '<'), + ], [], 0, 0); + $idsAsientos = array_unique(array_column($asientos, Asiento::primaryColumn())); + + if(empty($idsAsientos)) { + Tools::log()->warning('accounting-entry-not-found'); + return []; + } + + $partidas = Partida::all([ + new DataBaseWhere('idasiento', $idsAsientos, 'IN'), + new DataBaseWhere('codsubcuenta', $subcuentas, 'IN') + ], [], 0, 0); + + $partidasAgrupadas = []; + foreach ($partidas as $partida) { + $partidasAgrupadas[$partida->codsubcuenta][] = $partida; + } + + return $partidasAgrupadas; + } +} \ No newline at end of file diff --git a/Lib/Modelo303Calculator.php b/Lib/Modelo303Calculator.php new file mode 100644 index 0000000..2ded2a1 --- /dev/null +++ b/Lib/Modelo303Calculator.php @@ -0,0 +1,199 @@ + $movimientos) { + foreach ($movimientos as $mov) { + // IVA 4% + if (in_array($subcuenta, $subcuentasSegunIVA[4]['repercutido'])) { + $modelo303->add('01', $mov->baseimponible); + $modelo303->add('03', $mov->haber); + } + + // IVA 10% + if (in_array($subcuenta, $subcuentasSegunIVA[10]['repercutido'])) { + $modelo303->add('04', $mov->baseimponible); + $modelo303->add('06', $mov->haber); + } + + // IVA 21% + if (in_array($subcuenta, $subcuentasSegunIVA[21]['repercutido'])) { + $modelo303->add('07', $mov->baseimponible); + $modelo303->add('09', $mov->haber); + } + + // IVA 0% + if (in_array($subcuenta, $subcuentasSegunIVA[0]['repercutido'])) { + $modelo303->add('150', $mov->baseimponible); + $modelo303->add('152', $mov->haber); + } + + // RECARGO 1.75% + if (in_array($subcuenta, $subcuentasSegunRecargo[1.75]['repercutido'])) { + $modelo303->add('156', $mov->baseimponible); + $modelo303->add('158', $mov->haber); + } + + // RECARGO 0.5% + if (in_array($subcuenta, $subcuentasSegunRecargo[0.5]['repercutido'])) { + $modelo303->add('168', $mov->baseimponible); + $modelo303->add('170', $mov->haber); + } + + // RECARGO 1.4% + if (in_array($subcuenta, $subcuentasSegunRecargo[1.4]['repercutido'])) { + $modelo303->add('19', $mov->baseimponible); + $modelo303->add('21', $mov->haber); + } + + // RECARGO 5.2% + if (in_array($subcuenta, $subcuentasSegunRecargo[5.2]['repercutido'])) { + $modelo303->add('22', $mov->baseimponible); + $modelo303->add('24', $mov->haber); + } + } + } + + // Total cuota devengada + $modelo303->set('27', $modelo303->get('152') + $modelo303->get('167') + $modelo303->get('03') + $modelo303->get('155') + $modelo303->get('06') + $modelo303->get('09') + $modelo303->get('11') + $modelo303->get('13') + $modelo303->get('15') + $modelo303->get('158') + $modelo303->get('170') + $modelo303->get('18') + $modelo303->get('21') + $modelo303->get('24') + $modelo303->get('26')); + + /** + * IVA DEDUCIBLE + */ + // Por cuotas soportadas en operaciones interiores corrientes + foreach ($partidasAgrupadas as $subcuenta => $movimientos) { + foreach ($movimientos as $mov) { + // IVA 4% + if (in_array($subcuenta, $subcuentasSegunIVA[4]['soportado'])) { + $modelo303->add('28', $mov->baseimponible); + $modelo303->add('29', $mov->debe); + } + + // IVA 10% + if (in_array($subcuenta, $subcuentasSegunIVA[10]['soportado'])) { + $modelo303->add('28', $mov->baseimponible); + $modelo303->add('29', $mov->debe); + } + + // IVA 21% + if (in_array($subcuenta, $subcuentasSegunIVA[21]['soportado'])) { + $modelo303->add('28', $mov->baseimponible); + $modelo303->add('29', $mov->debe); + } + } + } + + // Total a deducir + $modelo303->set('45', $modelo303->get('29') + $modelo303->get('31') + $modelo303->get('33') + $modelo303->get('35') + $modelo303->get('37') + $modelo303->get('39') + $modelo303->get('41') + $modelo303->get('42') + $modelo303->get('43') + $modelo303->get('44')); + + // Resultado régimen general + $modelo303->set('46', $modelo303->get('27') - $modelo303->get('45')); + + // Información adicional + // Ventas intracomunitarias + $modelo303->set('59', self::getNetoFacturasVentasIntra($codejercicio, $fechainicio, $fechafin)); + + // Compras intracomunitarias + $totalesFacturasComprasIntra = self::getTotalesFacturasComprasIntra($codejercicio, $fechainicio, $fechafin); + $baseFacturasComprasIntra = $totalesFacturasComprasIntra['base']; + $cuotaFacturasComprasIntra = $totalesFacturasComprasIntra['cuota']; + + $modelo303->set('10', $baseFacturasComprasIntra); + $modelo303->set('11', $cuotaFacturasComprasIntra); + + return $modelo303; + } + + /** + * obtenemos los códigos de subcuentas agrupados según tipo iva + * esto lo hacemos por si existen varios impuestos + * del mismo iva y distintas subcuentas + * + * @param array $impuestos + * + * @return array + */ + public static function getSubAccountCodesByTax(array $impuestos): array + { + $subcuentasSegunIVA = []; + foreach ($impuestos as $impuesto) { + $subcuentasSegunIVA[$impuesto->iva]['repercutido'][] = $impuesto->codsubcuentarep; + $subcuentasSegunIVA[$impuesto->iva]['soportado'][] = $impuesto->codsubcuentasop; + } + return $subcuentasSegunIVA; + } + + /** + * obtenemos los codigos de subcuentas agrupados según tipo recargo + * esto lo hacemos por si existen varios impuestos + * del mismo recargo y distintas subcuentas + * + * @param array $impuestos + * + * @return array + */ + public static function getSubAccountCodesBySurchargeType(array $impuestos): array + { + $subcuentasSegunRecargo = []; + foreach ($impuestos as $impuesto) { + $subcuentasSegunRecargo[$impuesto->recargo]['repercutido'][] = $impuesto->codsubcuentarepre; + $subcuentasSegunRecargo[$impuesto->recargo]['soportado'][] = $impuesto->codsubcuentasopre; + } + return $subcuentasSegunRecargo; + } + + /** + * @throws KernelException + */ + private static function getNetoFacturasVentasIntra(string $codejercicio, string $fechainicio, string $fechafin) + { + $dataBase = new DataBase(); + + $sql = "SELECT SUM(neto) AS neto FROM facturascli "; + $sql .= "WHERE codejercicio = " . $dataBase->var2str($codejercicio) . " AND "; + $sql .= "COALESCE(fechadevengo, fecha) >= " . $dataBase->var2str($fechainicio) . " AND "; + $sql .= "COALESCE(fechadevengo, fecha) < " . $dataBase->var2str($fechafin) . " AND "; + $sql .= "operacion = " . $dataBase->var2str(InvoiceOperation::INTRA_COMMUNITY) . ";"; + + return $dataBase->select($sql)[0]['neto']; + } + + /** + * @throws KernelException + */ + private static function getTotalesFacturasComprasIntra(string $codejercicio, string $fechainicio, string $fechafin) + { + $dataBase = new DataBase(); + + $sql = "SELECT SUM(neto) AS base, SUM(totaliva) AS cuota FROM facturasprov "; + $sql .= "WHERE codejercicio = " . $dataBase->var2str($codejercicio) . " AND "; + $sql .= "COALESCE(fechadevengo, fecha) >= " . $dataBase->var2str($fechainicio) . " AND "; + $sql .= "COALESCE(fechadevengo, fecha) < " . $dataBase->var2str($fechafin) . " AND "; + $sql .= "operacion = " . $dataBase->var2str(InvoiceOperation::INTRA_COMMUNITY) . ";"; + + return $dataBase->select($sql)[0]; + } +} \ No newline at end of file