diff --git a/Init.php b/Init.php index 7c0a6a9..e413d24 100644 --- a/Init.php +++ b/Init.php @@ -156,6 +156,7 @@ private function setupSettings(): void { Tools::settings('proyectos', 'patron', 'PR-{ANYO}-{NUM}'); Tools::settings('proyectos', 'longnumero', 6); + Tools::settings('proyectos', 'reiniciarpatronanualmente', 0); Tools::settingsSave(); } } diff --git a/Lib/ProjectCodeGenerator.php b/Lib/ProjectCodeGenerator.php index 551ee35..06c6459 100644 --- a/Lib/ProjectCodeGenerator.php +++ b/Lib/ProjectCodeGenerator.php @@ -21,6 +21,7 @@ use FacturaScripts\Core\Tools; use FacturaScripts\Plugins\Proyectos\Model\Proyecto; +use FacturaScripts\Core\Base\DataBase\DataBaseWhere; /** * Description of ProjectCodeGenerator @@ -37,9 +38,55 @@ public static function new(&$project) { $patron = Tools::settings('proyectos', 'patron', 'PR-{ANYO}-{NUM}'); $long_numero = Tools::settings('proyectos', 'longnumero', 6); + $reset = (bool) Tools::settings('proyectos', 'reiniciarpatronanualmente', 0); $proyecto = new Proyecto(); - $numero = 1 + $proyecto->count(); + + if (!$reset) { + // default behaviour: keep existing global counting + $numero = 1 + $proyecto->count(); + } else { + // build prefix replacing date placeholders but leaving numeric placeholders empty + $replacements = [ + '{ANYO}' => date('Y'), + '{ANYO2}' => date('y'), + '{MES}' => date('m'), + '{DIA}' => date('d'), + '{NUM}' => '', + '{0NUM}' => '' + ]; + + $prefix = strtr($patron, $replacements); + + // find projects that start with the same prefix and belong to the same company, limited to current year + $year = date('Y'); + $where = [ + new DataBaseWhere('nombre', $prefix . '%', 'LIKE'), + new DataBaseWhere('idempresa', $project->idempresa), + new DataBaseWhere('fecha', $year . '-01-01', '>='), + new DataBaseWhere('fecha', $year . '-12-31', '<=') + ]; + $projects = Proyecto::all($where, [], 0, 0); + + $max = 0; + foreach ($projects as $p) { + if (empty($p->fecha)) { + continue; + } + $pYear = date('Y', strtotime($p->fecha)); + if ($pYear !== $year) { + continue; + } + if (preg_match('/(\\d+)$/', $p->nombre, $m)) { + $num = intval($m[1]); + if ($num > $max) { + $max = $num; + } + } + } + + $numero = $max + 1; + } $project->nombre = strtr($patron, [ '{ANYO}' => date('Y'), diff --git a/Test/main/ProyectoPatternResetTest.php b/Test/main/ProyectoPatternResetTest.php new file mode 100644 index 0000000..43cf16b --- /dev/null +++ b/Test/main/ProyectoPatternResetTest.php @@ -0,0 +1,65 @@ +nombre = strtr($patron, [ + '{ANYO}' => (string)$prevYear, + '{ANYO2}' => substr((string)$prevYear, 2), + '{MES}' => '01', + '{DIA}' => '01', + '{NUM}' => '5', + '{0NUM}' => str_pad('5', $long, '0', STR_PAD_LEFT) + ]); + $old->fecha = $prevYear . '-01-01'; + $old->descripcion = 'old'; + $this->assertTrue($old->save()); + + // crear proyecto nuevo (debe generarse y empezar en 1) + $new = new Proyecto(); + $new->descripcion = 'nuevo'; + $this->assertTrue($new->save()); + + $this->assertMatchesRegularExpression('/(\\d+)$/', $new->nombre, 'El nombre generado debe terminar en dígitos'); + preg_match('/(\\d+)$/', $new->nombre, $m); + $this->assertEquals(1, intval($m[1]), 'Se esperaba que la numeración empiece en 1 para el ejercicio actual'); + + // limpieza + $this->assertTrue($new->delete()); + $this->assertTrue($old->delete()); + } + + protected function tearDown(): void + { + $this->logErrors(); + } +} diff --git a/Translation/en_EN.json b/Translation/en_EN.json index 501526e..4822e3f 100644 --- a/Translation/en_EN.json +++ b/Translation/en_EN.json @@ -7,8 +7,9 @@ "phases": "Phases", "project-stock-rebuild-error": "Error rebuilding project stock", "project-stock-rebuild-ok": "Project stock rebuilt successfully", + "reiniciar-patron-anualmente": "Reset pattern annually", "show-project-stock": "Show project stock", "tasks-imported-correctly": "Tasks imported correctly", "total-pending-invoice": "Pending invoice", "unlink-document": "Unlink..." -} \ No newline at end of file +} diff --git a/Translation/es_ES.json b/Translation/es_ES.json index 6b59434..2d4c1d8 100644 --- a/Translation/es_ES.json +++ b/Translation/es_ES.json @@ -7,8 +7,9 @@ "phases": "Fases", "project-stock-rebuild-error": "Error al regenerar el stock", "project-stock-rebuild-ok": "Stock regenerado correctamente", + "reiniciar-patron-anualmente": "Reiniciar patrón anualmente", "show-project-stock": "Mostrar stock del proyecto", "tasks-imported-correctly": "Tareas importadas correctamente", "total-pending-invoice": "Pendiente facturar", "unlink-document": "Desvincular..." -} \ No newline at end of file +} diff --git a/XMLView/ConfigProyectos.xml b/XMLView/ConfigProyectos.xml index 44f4d29..240a334 100644 --- a/XMLView/ConfigProyectos.xml +++ b/XMLView/ConfigProyectos.xml @@ -8,6 +8,9 @@ + + + @@ -21,4 +24,4 @@ - \ No newline at end of file +