Módulos do guia

Nível 0 · Fundamentos · Módulo 01

Seu primeiro CRUD sem código

Duração estimada: 2h a 3h

Você vai sair sabendo

  • →Entender o que é o Dicionário da Aplicação e por que ele existe
  • →Criar tabelas e colunas no banco sem escrever SQL
  • →Escolher a referência certa para cada tipo de campo
  • →Montar uma janela com cabeçalho e linhas e publicá-la no menu

Checkpoint: 0 de 7

ver .md

Antes de começar

  • Módulo 00 concluído: servidor rodando e login como System funcionando.
  • Deixe o psql aberto num terminal, conectado ao banco. Você vai conferir no banco cada coisa que criar na tela:
psql -h localhost -U adempiere idempiere

O que você vai construir

A primeira versão do projeto que acompanha todo o guia: o controle de visitas técnicas da GardenWorld. Uma janela com:

  • Visita (cabeçalho): cliente, técnico responsável, data, tipo de visita e se é urgente
  • Linhas: produtos usados na visita, com quantidade

Sem nenhuma linha de Java. Nos próximos módulos, o mesmo projeto ganha regras, código, relatórios e fluxo de aprovação.

O Dicionário da Aplicação, em 1 minuto

No iDempiere, telas, campos, validações e menus não são programados: são cadastrados. Tudo isso fica em tabelas do próprio banco, com prefixo AD_ (de Application Dictionary). Quando você abre uma janela, o iDempiere lê essas definições e monta a tela na hora.

Consequências práticas:

  • Um CRUD completo (listar, filtrar, criar, editar, excluir, anexar, auditar, exportar) sai de graça ao cadastrar a janela.
  • Mudar um rótulo ou esconder um campo não exige compilar nem reiniciar.
  • O código Java fica reservado para as regras de negócio, que vêm a partir do módulo 04.

O Dicionário só pode ser alterado no perfil System. Entre com System / System e escolha o perfil System Administrator.

Passo a passo

1. Tipo de entidade: diga de quem é a customização

Conceito: todo registro do Dicionário tem um Entity Type (tipo de entidade). Ele diz a quem aquilo pertence: D é o core do iDempiere, e cada plugin ou customização deve ter o seu. É o que permite separar o que é seu do que é do core, exportar só o seu trabalho e gerar as classes Java no pacote certo (módulo 04).

Abra a janela Entity Type e crie:

CampoValor
Entity TypeEDU
NameGuia iDempiere

Salve. Se o EDU não aparecer nas listas dos próximos passos, saia e entre de novo: a lista de tipos de entidade fica em cache.

2. Tabela da visita

Conceito: a janela Table and Column (Tabela e Coluna) é a definição de uma tabela do banco dentro do Dicionário. Você cadastra a tabela e as colunas ali, e o iDempiere gera o CREATE TABLE e o ALTER TABLE.

Abra Table and Column e crie um registro:

CampoValor
DB Table NameEDU_Visita
NameVisita Técnica
Data Access LevelClient+Organization
Entity TypeEDU

Salve. Agora clique na engrenagem (processos) e rode Create/Complete Table. Na janela de parâmetros, deixe marcado só Create KeyColumn e confirme.

Esse processo cadastra a chave primária (EDU_Visita_ID), a coluna de UUID (EDU_Visita_UU) e as colunas padrão que toda tabela do iDempiere tem:

ColunaPara quê
AD_Client_IDEmpresa (tenant) dona do registro
AD_Org_IDOrganização dentro da empresa
IsActiveDesativar sem excluir
Created, CreatedByQuando e quem criou
Updated, UpdatedByQuando e quem alterou por último

Ainda não existe nada no banco. Confira no psql:

\d edu_visita
-- Did not find any relation named "edu_visita".

O processo só criou a definição. A tabela física nasce ao sincronizar a primeira coluna (passo 6).

3. Elemento: o significado de um campo

Conceito: um Element (elemento) define o nome da coluna no banco e o rótulo que o usuário vê, com as traduções. Colunas com o mesmo elemento, em qualquer tabela, têm o mesmo nome e o mesmo rótulo. Por isso, antes de criar um elemento, procure se o core já tem um: C_BPartner_ID, Description, Qty e M_Product_ID já existem e são reaproveitados.

Na janela Element, crie três elementos novos, todos com Entity Type EDU:

DB Column NameNamePrint Text
EDU_DataVisitaData da VisitaData
EDU_TipoVisitaTipo de VisitaTipo
EDU_IsUrgenteUrgenteUrgente

Convenção: colunas booleanas começam com Is, e colunas que apontam para outra tabela terminam com _ID. O iDempiere depende dessa segunda regra: é pelo sufixo _ID que ele descobre a tabela referenciada.

4. Validação dinâmica: filtrar o que aparece

Conceito: uma Dynamic Validation é um trecho de WHERE aplicado a um campo de referência. Serve para mostrar só os registros que fazem sentido.

No cliente, só interessam parceiros que são clientes. Abra Validation Rules (Regras de Validação) e crie:

CampoValor
NameEDU - Somente Clientes
TypeSQL
Validation codeC_BPartner.IsCustomer='Y'
Entity TypeEDU

Você vai usar essa regra na coluna C_BPartner_ID, no passo 6.

Para o técnico não é preciso criar nada. O core já tem uma referência pronta, AD_User - Internal, que lista só usuários ligados a funcionários ou representantes de vendas. Validação dinâmica filtra uma referência; uma referência de tabela já pode vir filtrada de fábrica. Antes de criar, procure o que o core já oferece.

5. Lista de valores fixos

Conceito: uma referência do tipo List tem as opções cadastradas no Dicionário. No banco fica gravado só o código (IN); o usuário vê o nome (Instalação), já traduzido.

Abra a janela Reference e crie:

CampoValor
NameEDU_TipoVisita
Validation TypeList Validation
Entity TypeEDU

Na aba List Validation, cadastre:

Search KeyName
INInstalação
MAManutenção
OROrçamento

Essa referência vai no campo Reference Key da coluna EDU_TipoVisita, no próximo passo.

6. Colunas da visita e a escolha da referência

Conceito: a Reference (referência) de uma coluna define duas coisas ao mesmo tempo: o tipo de dado no banco e o componente de tela. É a decisão mais importante ao criar uma coluna.

As referências que você vai usar agora:

ReferênciaTelaBancoQuando usar
Stringcaixa de textoVARCHARtexto curto
DatecalendárioTIMESTAMPdatas
Yes-NocheckboxCHAR(1) Y/Nbooleanos
Listlista suspensaVARCHARopções fixas definidas no Dicionário
Table Directlista suspensaNUMERIC (FK)o nome da coluna é igual ao da tabela + _ID (C_BPartner_ID → C_BPartner) e há poucos registros
Tablelista suspensaNUMERIC (FK)o nome da coluna não bate com a tabela (SalesRep_ID → AD_User); o campo Reference Key aponta uma referência que diz qual é a tabela
Searchcampo com lupaNUMERIC (FK)a tabela tem muitos registros; abre uma janela de busca em vez de carregar tudo numa lista

Na aba Column da tabela EDU_Visita, crie as colunas abaixo. Depois de salvar cada uma, clique em Synchronize Column: é esse botão que roda o ALTER TABLE no banco (na primeira vez, o CREATE TABLE).

DB Column NameReferenceDetalhes
C_BPartner_IDSearchMandatory. Dynamic Validation: EDU - Somente Clientes
SalesRep_IDTableReference Key: AD_User - Internal
EDU_DataVisitaDateMandatory. Default Logic: @#Date@
EDU_TipoVisitaListLength: 2. Mandatory. Reference Key: EDU_TipoVisita
EDU_IsUrgenteYes-NoDefault Logic: N
DescriptionStringLength: 255

Em C_BPartner_ID e EDU_DataVisita, marque também Identifier (Sequence 1 e 2). O identificador é o que aparece quando outra tela aponta para este registro: em vez de 1000001, o usuário vê Joe Block_2026-09-23.

Agora confira no psql:

\d edu_visita

A tabela existe, com as colunas padrão e as suas.

7. Tabela das linhas

Repita o passo 2 para a tabela EDU_VisitaLinha (Name Linha da Visita, mesmo Access Level e Entity Type) e rode o Create/Complete Table com Create KeyColumn.

Crie as colunas:

DB Column NameReferenceDetalhes
EDU_Visita_IDTable DirectMandatory. Parent link column marcado
LineIntegerMandatory. Default Logic: @SQL=SELECT COALESCE(MAX(Line),0)+10 FROM EDU_VisitaLinha WHERE EDU_Visita_ID=@EDU_Visita_ID@
M_Product_IDSearchMandatory. Identifier
QtyQuantityMandatory. Default Logic: 1
DescriptionStringLength: 255

Parent link column diz ao iDempiere que esta coluna liga a linha ao cabeçalho. É ela que faz a aba de linhas mostrar só as linhas da visita selecionada.

A Default Logic de Line numera as linhas de 10 em 10, como fazem os pedidos do core. Com @SQL=, o valor padrão vem de uma consulta.

8. A janela

Conceito: uma Window (janela) tem uma ou mais Tabs (abas), e cada aba mostra os Fields (campos) de uma tabela. O Tab Level (nível) define a hierarquia: nível 0 é o cabeçalho, nível 1 é filho do nível 0, e assim por diante.

Abra Window, Tab and Field e crie:

CampoValor
NameVisita Técnica
Window TypeMaintain
Entity TypeEDU

Na aba Tab, crie duas abas:

NameTableTab LevelSequence
VisitaEDU_Visita010
LinhasEDU_VisitaLinha120

Em cada aba, clique em Create Fields. O iDempiere cria um campo para cada coluna da tabela.

O rótulo de cada campo vem do elemento. O elemento SalesRep_ID do core se chama Sales Representative, mas aqui ele é o técnico. Para trocar o rótulo só nesta janela, abra o campo na aba Field, desmarque Centrally maintained e mude o Name para Técnico. O elemento do core continua intacto.

Para organizar a tela, use a engrenagem da aba e abra o Tab Editor: arraste os campos até a posição desejada. Deixe Cliente e Data na primeira linha, Tipo, Técnico e Urgente na segunda, e Description ocupando a largura toda.

Por fim, volte a Table and Column e preencha o campo Window das duas tabelas com Visita Técnica. É isso que faz o zoom (clicar num campo que aponta para uma visita e abrir a janela certa) funcionar.

9. Menu e acesso

Abra a janela Menu e crie:

CampoValor
NameVisita Técnica
ActionWindow
WindowVisita Técnica
Entity TypeEDU

Salve e, na árvore do menu, arraste a entrada para dentro de uma pasta (por exemplo, Partner Relations). Não deixe itens soltos na raiz: um menu desorganizado é o primeiro sinal de uma instalação malcuidada.

A janela ainda não aparece para o GardenAdmin porque o perfil dele não tem acesso a ela. Saia do System, entre como GardenAdmin, rode o processo Role Access Update e depois saia e entre de novo.

10. Teste

Como GardenAdmin, abra Visita Técnica e cadastre uma visita:

  1. No Cliente, clique na lupa. Só clientes aparecem (confirme que fornecedores ficam de fora).
  2. Escolha o Tipo, marque Urgente e salve.
  3. Vá para a aba Linhas e adicione dois produtos. Repare que Line vem preenchido com 10 e depois 20.
  4. Volte ao cabeçalho e veja o que vem de graça: busca, histórico de alterações, anexos, exportação e modo grade.

Confira no banco:

SELECT v.edu_visita_id, bp.name, v.edu_tipovisita, v.edu_isurgente
FROM edu_visita v JOIN c_bpartner bp USING (c_bpartner_id);

Checkpoint

0 de 7 itens

Erros comuns

SintomaCausa provávelCorreção
A tabela não existe no bancoNenhuma coluna foi sincronizadaClique em Synchronize Column em qualquer coluna
Erro ao sincronizar coluna obrigatóriaA tabela já tem registros e a coluna não tem valor padrãoPreencha Default Logic e sincronize de novo
A janela não aparece no menuFaltou o Role Access Update ou o novo loginRode o processo como GardenAdmin e entre de novo
A aba Linhas mostra linhas de todas as visitasEDU_Visita_ID sem Parent link columnMarque o campo e recrie os campos da aba
A lista de técnicos vem vaziaNenhum usuário está ligado a um parceiro marcado como funcionário ou representante de vendasNa janela Business Partner, marque Employee ou Sales Representative no parceiro do usuário
O lookup mostra números em vez de nomesA tabela referenciada não tem IdentifierMarque o identificador nas colunas certas
O EDU não aparece nas listas de Entity TypeCacheSaia e entre de novo
@SQL= da coluna Line dá erroErro de digitação no SQLTeste a consulta no psql, trocando @EDU_Visita_ID@ por um ID real

Desafio

Adicione à visita um campo Endereço de Atendimento que aponte para os endereços do parceiro (C_BPartner_Location_ID) e mostre apenas os endereços do cliente escolhido no cabeçalho.

Dica: a validação dinâmica pode usar o valor de outro campo da mesma tela com @NomeDaColuna@. Procure antes se o core já tem uma regra pronta para isso.

Referência

Campos importantes da coluna

CampoEfeito
MandatoryNOT NULL no banco e obrigatório na tela. Se marcado depois que a coluna já tem dados, vale só na tela
UpdatableSe desmarcado, o valor não pode mudar depois de salvo
IdentifierCompõe o texto que representa o registro em outras telas
Parent link columnLiga a aba filha à aba pai
Default LogicValor inicial (constante, @variável@ ou @SQL=)
Synchronize ColumnAplica a definição no banco (CREATE/ALTER TABLE)

Para remover uma coluna do banco, rode o processo Drop Database Column na aba Column antes de apagar o registro. Se apagar só o registro, a coluna fica órfã no banco.

Tipos de janela

Window TypeComportamento
MaintainCadastros: mostra todos os registros
TransactionMovimentos: ao abrir, mostra só os pendentes ou alterados recentemente
Query OnlySomente leitura

Atalho: Create Window, Tab and Field from Table

Depois de dominar o caminho manual, o processo Create Window, Tab and Field from Table, na janela Table and Column, cria janela, aba e menu de uma vez. Use o atalho só depois de ter feito o caminho manual pelo menos uma vez: quando algo der errado, você vai precisar saber o que ele fez.

Mais referências

A lista completa (Amount, Integer, Number, Text Long, Image, Button, Location, Chosen Multiple Selection e outras) está na janela Reference, filtrando por Validation Type = DataType.

Próximo módulo

02 · Janelas inteligentes: contexto e lógicas: campos que aparecem, somem, travam ou se preenchem conforme o que o usuário faz.