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
+