From 3dc64db22afc3369744205543bf5819b28740238 Mon Sep 17 00:00:00 2001 From: Abderrahim Darghal Belkacemi Date: Tue, 16 Jun 2026 10:44:04 +0200 Subject: [PATCH 1/5] fix: usar extends en vez de implements --- samples/CalculatorMod.php.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/CalculatorMod.php.sample b/samples/CalculatorMod.php.sample index 140598a..43ab410 100644 --- a/samples/CalculatorMod.php.sample +++ b/samples/CalculatorMod.php.sample @@ -12,7 +12,7 @@ use FacturaScripts\Core\Model\RegimenIVA; * * @see https://facturascripts.com/publicaciones/como-modificar-el-calculator-desde-un-plugin */ -class [[NAME]] implements CalculatorModClass +class [[NAME]] extends CalculatorModClass { /** @var string */ private $regimenIVA; From a28dc169c8bcb674bfe31040a7453b06d9ea8c9a Mon Sep 17 00:00:00 2001 From: Abderrahim Darghal Belkacemi Date: Tue, 16 Jun 2026 11:40:18 +0200 Subject: [PATCH 2/5] feat: update deprecated template --- samples/CalculatorMod.php.sample | 64 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/samples/CalculatorMod.php.sample b/samples/CalculatorMod.php.sample index 43ab410..62849af 100644 --- a/samples/CalculatorMod.php.sample +++ b/samples/CalculatorMod.php.sample @@ -5,71 +5,71 @@ namespace FacturaScripts\[[NAME_SPACE]]\Mod; use FacturaScripts\Core\Template\CalculatorModClass; use FacturaScripts\Core\Model\Base\BusinessDocument; use FacturaScripts\Core\Model\Base\BusinessDocumentLine; -use FacturaScripts\Core\Model\RegimenIVA; /** * Mod para modificar los cálculos de totales y subtotales de los albaranes, facturas, etc. - * + * * @see https://facturascripts.com/publicaciones/como-modificar-el-calculator-desde-un-plugin */ class [[NAME]] extends CalculatorModClass { - /** @var string */ - private $regimenIVA; - /** - * Podemos utilizar apply para aplicar configuraciones o precargar datos. + * Se ejecuta antes de los cálculos. Útil para precargar datos del documento. */ - public function apply(BusinessDocument &$doc, array &$lines): bool + public function apply(BusinessDocument $doc, array &$lines): string { - // Obtener y guardar el régimen de IVA una sola vez - // $subject = $doc->getSubject(); - // $this->regimenIVA = $subject->regimeniva ?? RegimenIVA::TAX_SYSTEM_GENERAL; - return true; + return $this->done(); } /** - * La función calculate se usa para recalcular el total del documento. + * Se ejecuta para recalcular el total del documento. */ - public function calculate(BusinessDocument &$doc, array &$lines): bool + public function calculate(BusinessDocument $doc, array &$lines): string { // $doc->total = 'aquí tu cálculo'; - return true; + return $this->done(); } /** - * Para recalcular las líneas de los documentos se usa calculateLine. + * Se ejecuta para recalcular cada línea del documento. */ - public function calculateLine(BusinessDocument $doc, BusinessDocumentLine &$line): bool + public function calculateLine(BusinessDocument $doc, BusinessDocumentLine $line): string { // $line->pvptotal = 'aquí tu cálculo'; - return true; + return $this->done(); + } + + /** + * Se ejecuta para inicializar los totales del documento a 0. + */ + public function clear(BusinessDocument $doc, array &$lines): string + { + return $this->done(); } /** - * Para inicializar los registros se usa clear. Normalmente se inicializan todos los valores a 0, - * aunque si es necesario se puede utilizar otro valor. + * Se ejecuta para acumular subtotales (neto, iva, etc.) desde las líneas. */ - public function clear(BusinessDocument &$doc, array &$lines): bool + public function accumulateSubtotals(array &$subtotals, BusinessDocument $doc, array &$lines): string { - /* - $doc->total = 0.0; - - foreach ($lines as $line) { - $line->total = 0.0; - } - */ - - return true; + return $this->done(); } /** - * Para modificar los subtotales se utiliza getSubtotals, donde los subtotales se especifican mediante un array. + * Se ejecuta para modificar los subtotales finales del documento. */ - public function getSubtotals(array &$subtotals, BusinessDocument $doc, array $lines) + public function updateSubtotals(array &$subtotals, BusinessDocument $doc, array $lines): string { // $subtotals['neto'] += 10; // $subtotals['total'] += 10; - return true; + return $this->done(); + } + + /** + * Se ejecuta al guardar el documento. + */ + public function save(BusinessDocument $doc, array &$lines): string + { + return $this->done(); } } From 0c13b5562333dd3b70a730f13a99ef336db61fcf Mon Sep 17 00:00:00 2001 From: Abderrahim Darghal Belkacemi Date: Tue, 16 Jun 2026 11:40:29 +0200 Subject: [PATCH 3/5] feat: add calculator updater --- src/FileUpdater.php | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/FileUpdater.php b/src/FileUpdater.php index 78a7b7a..558c378 100644 --- a/src/FileUpdater.php +++ b/src/FileUpdater.php @@ -259,6 +259,56 @@ public static function upgradePhpFiles(): void // reemplazamos contratos $fileStr = str_replace('use FacturaScripts\Core\Base\Contract\CalculatorModInterface;', 'use FacturaScripts\Core\Contract\CalculatorModInterface;', $fileStr); + + // migramos CalculatorModInterface (deprecado) a CalculatorModClass + if (strpos($fileStr, 'use FacturaScripts\Core\Contract\CalculatorModInterface;') !== false) { + $fileStr = str_replace( + 'use FacturaScripts\Core\Contract\CalculatorModInterface;', + 'use FacturaScripts\Core\Template\CalculatorModClass;', + $fileStr + ); + $fileStr = str_replace('implements CalculatorModInterface', 'extends CalculatorModClass', $fileStr); + + // normalizamos firmas de los métodos del Calculator (quitar & en $doc/$line, bool -> string) + $calcSignaturePatterns = [ + '/(public\s+function\s+apply\s*\(\s*BusinessDocument\s*)&(\s*\$doc\b[^)]*\))\s*:\s*bool/' => '$1$2: string', + '/(public\s+function\s+calculate\s*\(\s*BusinessDocument\s*)&(\s*\$doc\b[^)]*\))\s*:\s*bool/' => '$1$2: string', + '/(public\s+function\s+calculateLine\s*\([^)]*BusinessDocumentLine\s*)&(\s*\$line\s*\))\s*:\s*bool/' => '$1$2: string', + '/(public\s+function\s+clear\s*\(\s*BusinessDocument\s*)&(\s*\$doc\b[^)]*\))\s*:\s*bool/' => '$1$2: string', + '/(public\s+function\s+getSubtotals\s*\([^)]*\))\s*:\s*bool/' => '$1: string', + ]; + foreach ($calcSignaturePatterns as $pattern => $replacement) { + $fileStr = preg_replace($pattern, $replacement, $fileStr); + } + + // añadimos TODO encima de return true/false para que el dev complete la migración + if (strpos($fileStr, '// TODO: reemplazar por $this->done()') === false) { + $fileStr = preg_replace( + '/^(\s+)(return true;)/m', + '$1// TODO: reemplazar por $this->done()' . "\n" . '$1$2', + $fileStr + ); + } + if (strpos($fileStr, '// TODO: reemplazar por $this->stopAll()') === false) { + $fileStr = preg_replace( + '/^(\s+)(return false;)/m', + '$1// TODO: reemplazar por $this->stopAll() o $this->stopMods()' . "\n" . '$1$2', + $fileStr + ); + } + + Utils::echo( + " * AVISO: se ha migrado CalculatorModInterface -> CalculatorModClass.\n" . + " Se han corregido automáticamente:\n" . + " - use e implements/extends\n" . + " - firmas de métodos (& en \$doc/\$line eliminado, bool -> string)\n" . + " Revisa manualmente:\n" . + " - Los TODO encima de cada return true/false (cambiar a \$this->done(), etc.)\n" . + " - getSubtotals (reemplazado en el core por accumulateSubtotals/updateSubtotals)\n" . + " Más info: https://facturascripts.com/publicaciones/como-modificar-el-calculator-desde-un-plugin \n" + ); + } + $fileStr = str_replace('use FacturaScripts\Core\Base\Contract\PurchasesLineModInterface;', 'use FacturaScripts\Core\Contract\PurchasesLineModInterface;', $fileStr); $fileStr = str_replace('use FacturaScripts\Core\Base\Contract\PurchasesModInterface;', 'use FacturaScripts\Core\Contract\PurchasesModInterface;', $fileStr); $fileStr = str_replace('use FacturaScripts\Core\Base\Contract\SalesLineModInterface;', 'use FacturaScripts\Core\Contract\SalesLineModInterface;', $fileStr); From f9e50c65e7e75334061a59cb2e3afa27656342bf Mon Sep 17 00:00:00 2001 From: Abderrahim Darghal Belkacemi Date: Tue, 16 Jun 2026 11:42:29 +0200 Subject: [PATCH 4/5] fix: calculator creation bug --- src/Command/Mod/ModCommand.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Command/Mod/ModCommand.php b/src/Command/Mod/ModCommand.php index 2067e82..fd2f42a 100644 --- a/src/Command/Mod/ModCommand.php +++ b/src/Command/Mod/ModCommand.php @@ -85,9 +85,13 @@ private function createMod(string $name, string $sampleName, string $useClass, s // Escribir en Init.php $use = 'use ' . $useClass . ';'; $newInitContent = InitEditor::addUse($use); - InitEditor::setInitContent($newInitContent); + if ($newInitContent !== null) { + InitEditor::setInitContent($newInitContent); + } $newInitContent = InitEditor::addToInitFunction($initCode); - InitEditor::setInitContent($newInitContent); + if ($newInitContent !== null) { + InitEditor::setInitContent($newInitContent); + } return Command::SUCCESS; } From bbbd7f4bd68d4fe6b42a6c5088c1600a23dbb86c Mon Sep 17 00:00:00 2001 From: Abderrahim Darghal Belkacemi Date: Tue, 16 Jun 2026 12:04:04 +0200 Subject: [PATCH 5/5] feat: warnings system --- src/Command/Generator/UpgradeCommand.php | 1 + src/FileUpdater.php | 26 ++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Command/Generator/UpgradeCommand.php b/src/Command/Generator/UpgradeCommand.php index 507bb53..e7efa72 100644 --- a/src/Command/Generator/UpgradeCommand.php +++ b/src/Command/Generator/UpgradeCommand.php @@ -28,6 +28,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int FileUpdater::upgradeXmlFiles(); FileUpdater::upgradeTwigFiles(); FileUpdater::upgradeIniFile(); + FileUpdater::flushWarnings(); return Command::SUCCESS; } diff --git a/src/FileUpdater.php b/src/FileUpdater.php index 558c378..985e4a5 100644 --- a/src/FileUpdater.php +++ b/src/FileUpdater.php @@ -9,6 +9,24 @@ final class FileUpdater { const OK = " -> OK.\n"; + private static array $warnings = []; + + public static function flushWarnings(): void + { + if (empty(self::$warnings)) { + return; + } + + Utils::echo("\n⚠️ AVISOS IMPORTANTES — requieren revisión manual:\n"); + Utils::echo(str_repeat('-', 60) . "\n"); + foreach (self::$warnings as $warning) { + Utils::echo($warning); + } + Utils::echo(str_repeat('-', 60) . "\n"); + + self::$warnings = []; + } + private const WHERE_FACTORY_MAP = [ '=' => ['and' => 'eq', 'or' => 'orEq'], '!=' => ['and' => 'notEq', 'or' => 'orNotEq'], @@ -297,16 +315,16 @@ public static function upgradePhpFiles(): void ); } - Utils::echo( - " * AVISO: se ha migrado CalculatorModInterface -> CalculatorModClass.\n" . + self::$warnings[] = + " * AVISO en " . $pathFile . ": \n" . + " se ha migrado CalculatorModInterface -> CalculatorModClass.\n" . " Se han corregido automáticamente:\n" . " - use e implements/extends\n" . " - firmas de métodos (& en \$doc/\$line eliminado, bool -> string)\n" . " Revisa manualmente:\n" . " - Los TODO encima de cada return true/false (cambiar a \$this->done(), etc.)\n" . " - getSubtotals (reemplazado en el core por accumulateSubtotals/updateSubtotals)\n" . - " Más info: https://facturascripts.com/publicaciones/como-modificar-el-calculator-desde-un-plugin \n" - ); + " Más info: https://facturascripts.com/publicaciones/como-modificar-el-calculator-desde-un-plugin\n"; } $fileStr = str_replace('use FacturaScripts\Core\Base\Contract\PurchasesLineModInterface;', 'use FacturaScripts\Core\Contract\PurchasesLineModInterface;', $fileStr);