diff --git a/index.json b/index.json index 5210f5b..1c317b5 100755 --- a/index.json +++ b/index.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "last_updated": "2026-07-10", + "last_updated": "2026-07-13", "records": [ { "id": "KB-INFRA-001", @@ -807,6 +807,25 @@ "severity": "high", "path": "records/plugin-dev/KB-PLUGIN-041-glpi11-project-ticket-lifecycle-sync-and-componentized-card.md", "summary": "id: KB-PLUGIN-041" + }, + { + "id": "KB-PLUGIN-042", + "title": "\"GLPI 11 — ProjectTask::autoSetDate sobrescreve effective_duration (decorrido ≠ esforço); roll-up de esforço já é nativo via getTicketsTotalActionTime\"", + "domain": "plugin-dev", + "tags": [ + "glpi11", + "projecttask", + "tickettask", + "actiontime", + "effective-duration", + "time-tracking", + "gotcha", + "mindscrum" + ], + "status": "active", + "severity": "high", + "path": "records/plugin-dev/KB-PLUGIN-042-glpi11-effective-duration-overwrite-native-effort-rollup.md", + "summary": "id: KB-PLUGIN-042" } ] } diff --git a/records/plugin-dev/KB-PLUGIN-042-glpi11-effective-duration-overwrite-native-effort-rollup.md b/records/plugin-dev/KB-PLUGIN-042-glpi11-effective-duration-overwrite-native-effort-rollup.md new file mode 100644 index 0000000..cac3cd2 --- /dev/null +++ b/records/plugin-dev/KB-PLUGIN-042-glpi11-effective-duration-overwrite-native-effort-rollup.md @@ -0,0 +1,62 @@ +--- +id: KB-PLUGIN-042 +title: "GLPI 11 — ProjectTask::autoSetDate sobrescreve effective_duration (decorrido ≠ esforço); roll-up de esforço já é nativo via getTicketsTotalActionTime" +domain: plugin-dev +tags: + - glpi11 + - projecttask + - tickettask + - actiontime + - effective-duration + - time-tracking + - gotcha + - mindscrum +status: active +severity: high +created_at: 2026-07-13 +updated_at: 2026-07-13 +applies_to: + - GLPI 11.0.8 dev + - plugin mindscrum 0.6.0 +related_records: + - KB-PLUGIN-039 + - KB-PLUGIN-041 +--- + +# GLPI 11 — effective_duration é do core; esforço soma-se pelo helper nativo + +## Gotcha (descoberto em teste E2E que falhou) + +Gravar `effective_duration` numa `ProjectTask` via `update()` **não persiste** quando as +duas datas reais existem: `ProjectTask::autoSetDate()` (chamado em TODO add/update, +linhas ~538/579) **recalcula** `effective_duration = real_end_date - real_start_date` +(tempo DECORRIDO de calendário) e sobrescreve o input. Pior: se `percent_done=100` +chega com `real_start_date` vazio, o core seta start=now e end=now → effective=0. + +Decorrido ≠ esforço (task que atravessa 4 dias com 7h de trabalho). Não lute contra: +o campo pertence ao core com semântica de decorrido. + +## O roll-up de esforço JÁ É NATIVO (não armazenar, ler) + +Cadeia mantida pelo core: +1. `TicketTask.actiontime` (tempo gasto lançado pelo técnico); +2. `CommonITILTask::post_addItem/post_updateItem` → `updateActionTime()` mantém + `glpi_tickets.actiontime` = soma das tarefas do chamado; +3. `ProjectTask_Ticket::getTicketsTotalActionTime($projecttasks_id)` soma o + `actiontime` dos chamados vinculados à task de projeto (o próprio form nativo da + ProjectTask exibe isso, linha ~782 de ProjectTask.php). + +→ Para exibir "esforço real" de uma task de projeto, chamar o helper **ao vivo** a cada +render. Atualiza a cada lançamento (não só ao solucionar) e nunca briga com o core. + +## Padrão de time tracking do mindscrum (0.6.0) + +Mesmo input h:min, campo nativo por contexto: +- task de projeto → `planned_duration` (estimativa; persiste sem conflito); +- task de chamado → `actiontime` (efetivo; com `begin` setado o core recalcula `end`). +Planejado × realizado = `planned_duration` digitada × helper nativo somado. + +## Bônus — sessão CLI p/ testar TicketTask + +`TicketTask::add()` em script CLI exige `$_SESSION['glpigroups'] = []` +(senão `Reminder::getVisibilityCriteria` estoura com count(null) via PlanningEvent).