quarta-feira, 19 de janeiro de 2022

Colunas Dinâmicas com JARCH

     Devido a uma necessidade imposta em uma licitação o JARCH agora disponibiliza a funcionadade de adicionar uma coluna dinâmica em um CRUD. Gostaria de ressaltar que isso é uma solução desencorajada porque não faz muito sentido adicionar colunas sem existir alguma regra de negócio. 

Nesse post, vou mostrar como preparar uma funcionalidade para que seja possível o próprio usuário adicionar uma coluna no cadastro, bem como adicionar no filtro de pesquisa.

O primeiro passo e criar um script para criar as tabelas necessárias para utilização do JARCH no armazenamento da estrutura e dados, vou utilizar o FLYWAY com JARCH.

-- >>>>>>>>>>> SCRIPT FORMAT DATABASE ORACLE <<<<<<<<<<<<<
-- CREATE TABLE <SCHEMA>.TB_DYNAMICFIELD
CREATE TABLE TB_DYNAMICFIELD
(
ID_DYNAMICFIELD NUMBER(19) NOT NULL CONSTRAINT PK_DYNAMICFIELD PRIMARY KEY,
DH_EXCLUSAO TIMESTAMP,
SQ_VERSAOREGISTRO NUMBER(6) NOT NULL,
ID_MULTITENANT NUMBER(5) NOT NULL,
NM_PAGE VARCHAR2(500) NOT NULL,
NM_ENTITY VARCHAR2(500) NOT NULL,
NM_TABLE VARCHAR2(500) NOT NULL,
NM_LABEL VARCHAR2(50) NOT NULL,
NM_COLUMN VARCHAR2(50) NOT NULL,
TP_FIELD VARCHAR2(50) NOT NULL,
SQ_ROW NUMBER(6) NOT NULL,
SQ_COLUMN NUMBER(6) NOT NULL,
SN_VALUEREQUIRED CHAR(1) NOT NULL,
SN_DATATABLE CHAR(1) NOT NULL,
SQ_COLUMNDATATABLE NUMBER(6) NOT NULL,
SN_SEARCH CHAR(1) NOT NULL,
SQ_ROWSEARCH NUMBER(6) NOT NULL,
SQ_COLUMNSEARCH NUMBER(6) NOT NULL,
QT_SPANSEARCH NUMBER(6) NOT NULL
);

-- CREATE INDEXES FROM ADMFIS.TB_DYNAMICFIELD
CREATE INDEX DX_DYNAMICFIELDNMPAG ON TB_DYNAMICFIELD (NM_PAGE);
CREATE INDEX DX_DYNAMICFIELDNMCOL ON TB_DYNAMICFIELD (NM_COLUMN);
CREATE INDEX DX_DYNAMICFIELDNMLAB ON TB_DYNAMICFIELD (NM_LABEL);
CREATE INDEX DX_DYNAMICFIELDTPFIE ON TB_DYNAMICFIELD (TP_FIELD);

-- CREATE SEQUENCE FROM ADMFIS.TB_DYNAMICFIELD TO ID
CREATE SEQUENCE SQ_IDDYNAMICFIELD NOCACHE START WITH 0 MINVALUE 0 MAXVALUE 999999999999;

-- CREATE TABLE AUDIT FROM ADMFIS.TB_DYNAMICFIELD
CREATE TABLE TB_DYNAMICFIELD_AUD
(
ID_AUDITORIA NUMBER(19) NOT NULL,
TP_AUDITORIA NUMBER(1),
ID_DYNAMICFIELD NUMBER(19),
DH_EXCLUSAO TIMESTAMP,
SQ_VERSAOREGISTRO NUMBER(6),
ID_MULTITENANT NUMBER(5),
NM_PAGE VARCHAR2(500),
NM_ENTITY VARCHAR2(500),
NM_TABLE VARCHAR2(500),
NM_LABEL VARCHAR2(50),
NM_COLUMN VARCHAR2(50),
TP_FIELD VARCHAR2(50),
SQ_ROW NUMBER(6),
SQ_COLUMN NUMBER(6),
SN_VALUEREQUIRED CHAR(1),
SN_DATATABLE CHAR(1),
SQ_COLUMNDATATABLE NUMBER(6),
SN_SEARCH CHAR(1),
SQ_ROWSEARCH NUMBER(6),
SQ_COLUMNSEARCH NUMBER(6),
QT_SPANSEARCH NUMBER(6)

);

-- >>>>>>>>>>> SCRIPT FORMAT DATABASE ORACLE <<<<<<<<<<<<<
-- CREATE TABLE ADMFIS.TB_DYNAMICDATA
CREATE TABLE TB_DYNAMICDATA
(
ID_DYNAMICDATA NUMBER(19) NOT NULL CONSTRAINT PK_DYNAMICDATA PRIMARY KEY,
DH_EXCLUSAO TIMESTAMP,
SQ_VERSAOREGISTRO NUMBER(6) NOT NULL,
ID_MULTITENANT NUMBER(5) NOT NULL,
NM_PAGE VARCHAR2(500) NOT NULL,
NM_ENTITY VARCHAR2(500) NOT NULL,
NM_TABLE VARCHAR2(500) NOT NULL,
ID_ENTITY NUMBER NOT NULL,
NM_LABEL VARCHAR2(50) NOT NULL,
NM_COLUMN VARCHAR2(50) NOT NULL,
GN_VALUE VARCHAR2(4000),
GN_BINARY BLOB,
ID_DYNAMICFIELD NUMBER(19)
);

-- CREATE INDEXES FROM ADMFIS.TB_DYNAMICDATA
CREATE INDEX DX_DYNAMICDATACOMP1 ON TB_DYNAMICDATA (ID_DYNAMICFIELD, ID_ENTITY);
CREATE INDEX DX_DYNAMICDATANMPAG ON TB_DYNAMICDATA (NM_PAGE);
CREATE INDEX DX_DYNAMICDATANMCOL ON TB_DYNAMICDATA (NM_COLUMN);
CREATE INDEX DX_DYNAMICDATANMENT ON TB_DYNAMICDATA (NM_ENTITY);
CREATE INDEX DX_DYNAMICDATAIDENT ON TB_DYNAMICDATA (ID_ENTITY);
CREATE INDEX DX_DYNAMICDATANMLAB ON TB_DYNAMICDATA (NM_LABEL);

-- CREATE SEQUENCE FROM ADMFIS.TB_DYNAMICDATA TO ID
CREATE SEQUENCE SQ_IDDYNAMICDATA NOCACHE START WITH 0 MINVALUE 0 MAXVALUE 999999999999;

-- CREATE TABLE AUDIT FROM ADMFIS.TB_DYNAMICDATA
CREATE TABLE TB_DYNAMICDATA_AUD
(
ID_AUDITORIA NUMBER(19) NOT NULL,
TP_AUDITORIA NUMBER(1),
ID_DYNAMICDATA NUMBER(19),
DH_EXCLUSAO TIMESTAMP,
SQ_VERSAOREGISTRO NUMBER(6),
ID_MULTITENANT NUMBER(5),
NM_PAGE VARCHAR2(500),
NM_ENTITY VARCHAR2(500),
NM_TABLE VARCHAR2(500),
ID_ENTITY NUMBER,
NM_LABEL VARCHAR2(50),
NM_COLUMN VARCHAR2(50),
GN_VALUE VARCHAR2(4000),
GN_BINARY BLOB,
ID_DYNAMICFIELD NUMBER(19)
);

Nesse exemplo vou utilizar o caso de uso de Documento para disponibilizar a criação de ação dinâmica, então vou adicionar mais um script para facilitar a JPA na busca de informações:


CREATE VIEW ADMFIS.VW_DOCUMENTO_DYN AS SELECT * FROM ADMFIS.TB_DYNAMICDATA WHERE NM_ENTITY = 'DOCUMENTOENTITY';

Vou alterar minha entity DocumentoEntity para implementar a interface IDynamicColumn


public class DocumentoEntity extends UsuarioMultiTenantEntity implements IDynamicColumn {

E o mapeamento da coluna dinâmica na entidade DocumentoEntity:


@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(schema = "admfis", name = "vw_documento_dyn",
joinColumns = @JoinColumn(name = "id_entity", referencedColumnName = "id_documento"))
@MapKeyColumn(name = "nm_column")
@Column(name = "gn_value")
@Filter(name = Constant.TENANT)
private Map<String, String> dynamicColumn;

E o get e set:


@Override
public Map<String, String> getDynamicColumn() {
return dynamicColumn;
}

@Override
public void setDynamicColumn(Map<String, String> dynamicColumn) {
this.dynamicColumn = dynamicColumn;
}

Agora compilando e publicando a aplicação vou acessar a tela de lista de documentos:


Pressionando as teclas CTRL+SHIFT+F12 simultâneamente abre a tela para adicionar a coluna dinâmica.

Confirmando os dados agora temos:


E a tela de dados:


 

Conclusão

Essa funcionalidade deve ser usada somente se necessario, uma vez que a normalização da tabela não fica claro onde essa informação é gravado.

Até mais,


sábado, 15 de janeiro de 2022

Versão Final 21.12.0

 Introdução

Nesse post vou mostrar as principais novidades da versão 21.12.0, algumas correções e pequenas alterações.

Alterações

Além das implementações descritas acima foram feitas algumas alterações:
- Melhoria nos card's de filtro de relatório, para ser possível ajustar cor e ícone
- Ajuste nas mensagens de erros para colocar o campo na frente da mensagem automaticamente
- Alterado a nomenclatura da anotação JArchListActionConfiguration para JArchListController
- Refatoração no tratamento de mensagens pelo BundleUtils, BeanValidationUtils e MessagePropertiesUtils

Correções

Além das alterações descritas acima esta versão contempla algumas correções:
Ajuste na geração de mensagens de erros para não formatar a mensagem na camada de domínio
- Correção na busca por codigo do lookup, para não pesquisar por numero quando não for numero
- Alterado a busca do código lookup pra não ser case sensitive
- Correção no ocultação da menu que estava ocultando o main indevidamente

Implementações

Além das correções descritas acima esta versão contempla algumas correções:
- Adicionado nova biblioteca PhoneUtils para formatar o número de telefone
- Adicionado feature de coluna dinâmica para os caso de USO, com pesquisa e mostragem no datagrid
- dicionado os métodos isOracle() e isPostgreSql() no DatabaseUtils

Conclusão

Essa versão contempla algumas melhorias e correções. É recomendável a atualização para essa nova versão.

Até mais,

Versão 23.3.0-Final

      Introdução Nesse post vou mostrar as principais novidades da versão 23.3.0, algumas correções e pequenas alterações. Alterações Além d...