--- 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 (e visibilidade de Project) Scripts CLI que exercitam o core exigem `$_SESSION['glpigroups'] = []`: - `TicketTask::add()` → `Reminder::getVisibilityCriteria` estoura com count(null) via PlanningEvent; - `Project::getVisibilityCriteria()` (linha ~404) → mesmo count(null). No navegador `glpigroups` sempre existe (setado no login) — o sintoma é exclusivo de harness CLI com sessão mínima.