Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
6e5a33b
chore(proyectos): subir min_version a 2026.7 para los grupos de pestañas
abdedarghal111 Oct 12, 2026
85f7ea8
feat(EditProyecto): agrupar las pestañas de ventas y compras
abdedarghal111 Oct 12, 2026
4a53737
refactor(proyectos): usar mainTab() y mainTabModelValue() del core
abdedarghal111 Oct 12, 2026
01e8493
refactor(EditProyecto): simplificar autocompleteAction y quitar DataB…
abdedarghal111 Oct 12, 2026
62e2e5b
fix(EditProyecto): validar permisos, token y acceso en todas las acci…
abdedarghal111 Oct 12, 2026
e917f0e
fix(KanbanProyectos): validar token y acceso al mover tareas
abdedarghal111 Oct 12, 2026
bb4797d
fix(EditProyecto): cargar los recibos del proyecto y permitir pagarlos
abdedarghal111 Oct 12, 2026
af9038e
fix(EditProyecto): permitir buscar por numero2 al vincular documentos…
abdedarghal111 Oct 12, 2026
75fde57
fix(EditProyecto): comprobar el proyecto del documento al vincular y …
abdedarghal111 Oct 12, 2026
5cbe5d2
fix(EditProyecto): no vaciar toda la caché al regenerar el stock
abdedarghal111 Oct 12, 2026
3324645
fix(EditProyecto): ocultar el nombre del proyecto privado al denegar …
abdedarghal111 Oct 12, 2026
f2df808
fix(EditProyecto): avisar cuando no se desvincula ningún documento
abdedarghal111 Oct 12, 2026
b46b702
fix(KanbanProyectos): restaurar la dependencia sortablejs borrada en …
abdedarghal111 Oct 12, 2026
30db375
fix(KanbanProyectos): no guardar el movimiento al reordenar dentro de…
abdedarghal111 Oct 12, 2026
a2a26c7
fix(EditProyecto): ocultar vincular y desvincular sin permiso de modi…
abdedarghal111 Oct 12, 2026
71976d8
chore(proyectos): subir la versión del plugin a 5.22
abdedarghal111 Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
257 changes: 185 additions & 72 deletions Controller/EditProyecto.php

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Controller/EditTareaProyecto.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ protected function createViews()
? $this->getModel()->idproyecto
: $this->request->queryOrInput('idproyecto', '');

$this->tab($this->mainTabName())->addButton([
$this->mainTab()->addButton([
'type' => 'link',
'action' => 'KanbanProyectos?idproyecto=' . $idproyecto,
'icon' => 'fa-brands fa-trello',
Expand Down Expand Up @@ -133,7 +133,7 @@ protected function loadData($viewName, $view)
$this->setTemplate('Error/AccessDenied');
} elseif (false === $view->model->getProject()->editable) {
$this->disableTaskColumns($view);
$this->tab('EditTareaProyecto')->disableColumn('code');
$this->mainTab()->disableColumn('code');
}

// Si el modelo no existe, desactivamos la pestaña de archivos
Expand All @@ -144,15 +144,15 @@ protected function loadData($viewName, $view)
break;

case 'EditNotaProyecto':
$where = [Where::eq('idtarea', $this->tabModelValue($mainViewName, 'idtarea'))];
$where = [Where::eq('idtarea', $this->mainTabModelValue('idtarea'))];
$view->loadData('', $where, ['fecha' => 'DESC']);
if (false === $view->model->exists()) {
$view->model->idproyecto = $this->tabModelValue($mainViewName, 'idproyecto');
$view->model->idproyecto = $this->mainTabModelValue('idproyecto');
}
break;

case 'docfiles':
$this->loadDataDocFiles($view, $this->getModelClassName(), $this->tabModelValue($mainViewName, 'idtarea'));
$this->loadDataDocFiles($view, $this->getModelClassName(), $this->mainTabModelValue('idtarea'));
break;
}
}
Expand Down
28 changes: 22 additions & 6 deletions Controller/KanbanProyectos.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

use FacturaScripts\Core\Template\Controller;
use FacturaScripts\Core\Where;
use FacturaScripts\Dinamic\Lib\MultiRequestProtection;
use FacturaScripts\Dinamic\Model\EstadoProyecto;
use FacturaScripts\Dinamic\Model\FaseTarea;
use FacturaScripts\Dinamic\Model\Proyecto;
Expand Down Expand Up @@ -74,20 +75,32 @@ private function moveTaskAction(): void
if (false === $this->permissions->allowUpdate) {
$this->response()->json(['ok' => false, 'error' => 'not-allowed']);
return;
} elseif (false === $this->validateFormToken()) {
$this->response()->json(['ok' => false, 'error' => 'invalid-request']);
return;
}

// devolvemos un token nuevo para el siguiente movimiento
$token = (new MultiRequestProtection())->newToken();

$idtarea = (int) $this->request()->input('idtarea', '0');
$idfase = (int) $this->request()->input('idfase', '0');

$task = new TareaProyecto();
if ($idtarea > 0 && $task->load($idtarea)) {
$task->idfase = $idfase;
$task->save();
$this->response()->json(['ok' => true]);
if ($idtarea <= 0 || false === $task->load($idtarea)) {
$this->response()->json(['ok' => false, 'token' => $token]);
return;
}

// el usuario debe poder ver el proyecto y este debe ser editable
$project = $task->getProject();
if (false === $project->userCanSee($this->user) || false === $project->editable) {
$this->response()->json(['ok' => false, 'error' => 'not-allowed', 'token' => $token]);
return;
}

$this->response()->json(['ok' => false]);
$task->idfase = $idfase;
$this->response()->json(['ok' => $task->save(), 'token' => $token]);
}

private function loadProjects(): void
Expand All @@ -108,7 +121,10 @@ private function loadSelectedProject(): void

$this->project = new Proyecto();
if ($idproyecto > 0) {
$this->project->load($idproyecto);
// si el usuario no puede ver el proyecto, no lo cargamos
if ($this->project->load($idproyecto) && false === $this->project->userCanSee($this->user)) {
$this->project = new Proyecto();
}
} elseif (!empty($this->projects)) {
$this->project = $this->projects[0];
}
Expand Down
2 changes: 1 addition & 1 deletion Extension/Controller/EditCliente.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function loadData(): Closure
{
return function ($viewName, $view) {
if ($viewName === 'ListProyecto') {
$codcliente = $this->tabModelValue($this->mainTabName(), 'codcliente');
$codcliente = $this->mainTabModelValue('codcliente');
$where = [Where::eq('codcliente', $codcliente)];
$view->loadData('', $where);
}
Expand Down
2 changes: 1 addition & 1 deletion Extension/Controller/EditProducto.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function loadData(): Closure
{
return function ($viewName, $view) {
if ($viewName === 'ListStockProyecto') {
$idproducto = $this->tabModelValue($this->mainTabName(), 'idproducto');
$idproducto = $this->mainTabModelValue('idproducto');
$where = [Where::eq('idproducto', $idproducto)];
$view->loadData('', $where);
}
Expand Down
8 changes: 7 additions & 1 deletion View/KanbanProyectos.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
<script>
document.addEventListener('DOMContentLoaded', function () {
var editable = {{ fsc.project.editable and fsc.permissions.allowUpdate ? 'true' : 'false' }};
var multireqtoken = '{{ formToken(false) }}';

document.querySelectorAll('.kanban-column').forEach(function (column) {
new Sortable(column, {
Expand All @@ -215,7 +216,8 @@
chosenClass: 'sortable-chosen',
disabled: !editable,
onEnd: function (evt) {
if (evt.from === evt.to && evt.oldIndex === evt.newIndex) {
// el orden dentro de una fase no se guarda, solo el cambio de fase
if (evt.from === evt.to) {
return;
}

Expand All @@ -232,9 +234,13 @@
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'idtarea=' + taskId + '&idfase=' + newPhaseId
+ '&multireqtoken=' + encodeURIComponent(multireqtoken)
}).then(function (response) {
return response.json();
}).then(function (data) {
if (data.token) {
multireqtoken = data.token;
}
if (!data.ok) {
location.reload();
}
Expand Down
4 changes: 2 additions & 2 deletions facturascripts.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = 'Proyectos'
description = 'Permite gestionar proyectos, tareas, vincular usuarios, documentos de compra y de venta.'
version = 5.21
min_version = 2026.65
version = 5.22
min_version = 2026.7
compatible = 'FacturasProgramadas'
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "proyectos",
"private": true,
"dependencies": {
"sortablejs": "^1.15.6"
}
}
Loading