# Templates de Payload (2.0) A partir da versão 2.0, o plugin deixa de ter o corpo das requisições ao Redmine "chumbado" no código: cada operação passa a ter um **template de payload** editável, para que o plugin se adapte às **peculiaridades de cada Redmine** (campos personalizados obrigatórios, campos extras, textos fixos) sem precisar de alteração de código. > **Retrocompatível:** sem template **ativo**, o plugin se comporta **exatamente** > como nas versões 1.x. Você adota os templates quando (e se) quiser. ## Onde fica **Configurar → Plugins → Redmine Integration → "Templates de Payload (avançado)"**. Há um card por operação: | Operação | Quando dispara | Endpoint Redmine | |---|---|---| | **Criar tarefa (issue)** | 1º lançamento de tempo de um chamado | `POST /issues.json` | | **Lançar tempo** | tarefa (TicketTask) marcada como *Feito* | `POST /time_entries.json` | | **Atualizar status** | mudança de status do chamado | `PUT /issues/{id}.json` | | **Criar projeto** | vínculo "criar novo" na aba Redmine | `POST /projects.json` | ## O conceito: "DE → PARA" - **DE (variáveis do GLPI):** o que o plugin tem para oferecer — `chamado.titulo`, `tarefa.horas`, `vinculo.projeto_redmine`, etc. Aparecem como **autocomplete** no campo de valor de cada linha (e há uma lista de referência colapsável). - **PARA (campos do Redmine):** o que **o seu Redmine** espera em cada operação — descoberto automaticamente (campos padrão + **campos personalizados** via `GET /custom_fields.json`), com marcação de **obrigatório** e valores possíveis. Clicar num campo do "PARA" adiciona a linha no editor com o caminho já pronto. ## Fluxo recomendado 1. **Sincronizar Metadados** (aba Conexão) — é o que descobre trackers, status, atividades e **campos personalizados** do seu Redmine. 2. No card da operação, clique em **Gerar template** — cria o ponto de partida equivalente ao comportamento padrão **+ os campos obrigatórios do seu ambiente**. 3. Ajuste as linhas (o autocomplete ajuda a achar as variáveis do GLPI). 4. Clique em **Testar**: - **Preview** — mostra o JSON final renderizado com dados de exemplo (seguro). - **Teste real** (opcional) — cria e apaga um objeto de teste no Redmine e, se recusado, **traduz o erro** ("Atividade não pode ficar vazio → mapeie esse campo"). 5. Marque **Ativo** e clique em **Salvar** (o botão único no fim da página grava tudo). ## Sintaxe das tags ``` {{ variavel }} → valor da variável {{ variavel | filtro }} → aplica um filtro {{ variavel | filtro:arg }} → filtro com argumento {{ mapa[chave.dinamica] }} → lookup indexado (ex.: map.status[chamado.status]) ``` **Regra de tipos:** quando a tag ocupa **todo** o valor, o resultado sai com o **tipo nativo** da variável (número, array, booleano — sem aspas no JSON). Quando a tag está no meio de um texto, vira interpolação de string. Campos que resolverem para vazio/nulo são **omitidos** do payload. ### Filtros disponíveis | Filtro | Efeito | |---|---| | `truncar:N` | corta a string em N caracteres (ex.: `subject` no limite de 255) | | `sem_html` | remove HTML/entidades | | `minusculo` | tudo minúsculo | | `identificador` | normaliza para identificador Redmine válido (minúsculas, `-`) | | `padrao:'texto'` | valor fixo quando a variável estiver vazia | ## Variáveis do GLPI (o "DE") | Grupo | Variáveis | |---|---| | `chamado.*` | `id`, `titulo`, `descricao`, `status`, `entidade`, `tecnico` | | `tarefa.*` | `id`, `horas`, `segundos`, `descricao`, `comentario`, `data`, `autor` | | `vinculo.*` | `projeto_redmine`, `issue_redmine`, `categoria_padrao` | | `config.*` | `tracker_padrao`, `prioridade_padrao`, `atividade_padrao`, `observadores` | | `map.status` | mapa de status GLPI→Redmine (use como `map.status[chamado.status]`) | | `form.*` (criar projeto) | `nome`, `identificador`, `descricao`, `publico`, `subprojeto_de`, `trackers`, `modulos`, `cf_` | > **Autoria:** `chamado.tecnico` e `tarefa.autor` são **texto** (para usar em > comentários, por exemplo). A **autoria real** da issue/tempo continua automática, > via *impersonation* — não é um campo do template. ## Segurança e robustez - As tags são um mini-motor de substituição (mustache-like), **não** executam código (não é Twig completo) — seguro para edição por administradores. - Template com JSON inválido **não é salvo** (aviso na tela). - Se um template ativo falhar no **render** em produção, o plugin **cai no comportamento 1.x** e registra no log — nunca perde um lançamento. ## Exemplo (o que o "Gerar template" produz para `log_time`) ```json { "time_entry": { "issue_id": "{{ vinculo.issue_redmine }}", "hours": "{{ tarefa.horas }}", "comments": "{{ tarefa.comentario }}", "activity_id": "{{ config.atividade_padrao }}" } } ```