Package systextil.temp
Este framework é composto de três partes:
Formulário de zoom para cadastros temporários
Os registros temporários são definidos e guardados em memória através de formulários predefinidos
para isso. Todos eles são subclasses de forms.systextil.Temp
, que é o formulário básico para
cadastros temporários, funcionando como um formulário abstrato: ele já possui toda a lógica para
manusear os registros temporários, mas não contém nenhum campo na tela e não tem as regras e
os dados que vai usar.
Subclasses desse formulário devem implementar o seguinte, para que possam ser usadas:
- conter os campos na tela, necessariamente para preencher a chave do registro, e opcionalmente para preencher a descrição de cada registro;
- informar o nome do campo de descrição, se existir, na propriedade
String descriptionFieldName
; - implementar os métodos
protected void populateRecord(Object o) throws Exception
eprotected Object getCurrentRecord() throws Exception
, que trazem para a tela e devolvem para o programa o objeto de negócio que serve como a chave do registro. Esse objeto comumente é umInteger
ou umString
, mas pode ser qualquer objeto que sirva como chave, por exemploCnpj
ouCodProduto
.
As seguintes subclasses estão disponíveis para uso imediato no framework systextil
:
forms.systextil.TempNumeric
para registros cuja chave é um campo Numeric, com descriçãoforms.systextil.TempString
para registros cuja chave é um campo String, com descrição
Estes formulários por si só já atendem a uma grande quantidade de casos. Pode-se criar subclasses desses formulários
para fins mais específicos, contendo regras de negócio ou formatações, por exemplo. Essas subclasses
devem ser disponibilizadas para uso global no projeto systextil-widgets
dentro da package
forms.temp
(p. ex. forms.temp.Clientes
).
Se, eventualmente, a subclasse for para uso restrito de um módulo ou atrelada a esse módulo,
então deve ser disponibilizada dentro desse módulo com o nome Temp*
(p. ex. forms.pcpc.TempOrdensConfeccao
),
mas isto é desencorajado. Esse mesmo padrão deve se aplicar a plugins, se houver.
Componentes de texto do tipo "inclusão - exceção"
São o coração deste framework. São eles que contêm as regras, as validações e os dados que se
aplicam aos registros temporários. Na prática, incluir e configurar este componente numa tela de relatórios
é basicamente "arrastar" um objeto widgets.IncExc
(ou uma de suas subclasses) para sua posição no
formulário e preencher os atributos necessários.
Por exemplo, para configurar um cadastro temporário de depósitos, seria algo assim:
FIELD campo_63 extends widgets.IncExc { { zoomFormName = "forms.systextil.TempNumeric"; temp.title = "Cadastro temporário de depósitos"; temp.label = "Depósitos"; temp.zoomFormName = "forms.basi.basi_f570"; temp.zoomFyiMessage = "fy04459"; temp.validador = VAL; } private static final Val VAL = new Val(); private static class Val extends systextil.valid.ValidadorComDescricaoInt { Val() { super("ds05433"); } // Mensagem de depósito não cadastrado protected String lerDescricao(AppConnection conn, int cod) { String desc = systextil.dao.Deposito.getDescricao(conn, cod); return desc == null || desc.isEmpty() ? null : desc; } } }
Melhor ainda seria disponibilizar este componente já preenchido no projeto systextil-widgets
dentro da package
incexc
(p. ex. incexc.Depositos
). Assim, bastaria "arrastar" um objeto desses para o formulário,
definir seu nome e mais nada.
É altamente recomendado disponibilizar componentes já preenchidos no projeto systextil-widgets
dentro da package incexc
para reuso global, eliminando repetição de código e de configurações.
Mais detalhes estão no javadoc do componente global widgets.IncExc
.
Filtros automáticos na execução de processos agendados
O processo agendado obtém do banco de dados um mapa contendo os registros temporários que foram preenchidos, e com eles monta um filtro para cada campo que os preencheu. Cada filtro facilita a montagem do SQL para filtragem e outros dados de uso comum em relatórios.
Por exemplo, para incluir os filtros de depósitos e de empresas em um SQL, seria algo assim:
String cmdSQL5 = "select campo1, campo2, campo3 etc... " + "from basi_205, estq_040 " + "where basi_205.codigo_deposito = estq_040.deposito " + tempMap.get("campo_63").toSQL("basi_205", "codigo_deposito") + tempMap.get("campo_42").toSQL("basi_205", "local_deposito") + "and (estq_040.cditem_nivel99 = ? or ? = '0') " + "and (estq_040.cditem_grupo = ? or ? = '00000') " + "and (estq_040.cditem_subgrupo = ? or ? = '000') " + "and (estq_040.cditem_item = ? or ? = '000000') " + "etc...";
A variável tempMap
é um mapa que obtém um objeto do tipo TempFilter
para cada nome de campo. Esse objeto possui métodos utilitários para várias tarefas, como montar o SQL para
filtragem, concatenar a lista de itens recebidos, obter a lista desses itens para inspecionar seu conteúdo.
Uso de filtros em classes Java
Não é preciso um processo agendado para usar estes filtros. Pode-se alimentar um ou mais
TempFilter
s e usá-los mais adiante em qualquer processo Java.
Segue um modelo de como usar filtros com valores provenientes de uma lista de valores inteiros, de uma lista de objetos, e de uma lista de arrays.
Não é necessário o uso de tipos genéricos. Neste exemplo eles dão entendimento de como funcionam, mas não fazem diferença no uso final.
String filtrar(AppConnection conn, List<Integer> colecoes, List<Cnpj> clientes, List<Object[]> notasFiscais) throws Exception { // Filtro de coleções // Define como filtrar. INC = false, EXC = true TempRecords<Integer> recCol = new TempRecords<>("colecoes01", false, colecoes); // Alimenta o filtro com a definição TempFilter<Integer, Integer> filterColecoes = new TempFilter<>(recCol); // Insere os registros no banco de dados filterColecoes.insertRecords(conn); // Filtro de clientes // Define como filtrar. INC = false, EXC = true // Neste caso é preciso usar o conversor de Cnpj para array. // Felizmente já temos um pronto. É só usar. TempRecords<Integer[]> recsCnpj = new TempRecords<>("clientes01", false, clientes.stream() .map(Cnpj.TEMP_CONVERTER::toRaw) .collect(Collectors.toList())); // Alimenta o filtro com a definição TempFilter<Cnpj, Integer[]> filterCnpj = new TempFilter<>(recsCnpj); // Insere os registros no banco de dados filterCnpj.insertRecords(conn); // Filtro de notas fiscais // Define como filtrar. INC = false, EXC = true // Neste caso não é preciso usar um conversor, pois os dados já estão // em forma de array. TempRecords<Object[]> recsNF = new TempRecords<>("notas_fiscais01", false, notasFiscais); // Alimenta o filtro com a definição TempFilter<Object[], Object[]> filterNF = new TempFilter<>(recsNF); // Insere os registros no banco de dados filterNF.insertRecords(conn); // Uso dos filtros String SQL = "SELECT BLA FROM BLA " + "WHERE BLA " + filterColecoes.toSQL("pedi_100", "cod_colecao") + filterCnpj.toSQL("pedi_100", "cli9", "cli4", "cli2") + filterNF.toSQL("pedi_100", "codigo_empresa", "num_nota_fisc", "serie_nf") + "ORDER BY BLA"; return SQL; }
-
ClassDescriptionEm um formulário, controla todas as atividades relacionadas com a gravação de um conjunto de registros temporários associado a um campo.Representa o campo de inclusão e exclusão (e é implementada por ele), para que o controle de registros temporários possa preencher o valor desse campo na tela.TempConverter<F,
R extends Serializable> Faz a conversão entre objetos de negócio e registros temporários persistidos.TempFilter<F,R extends Serializable> Em um processo agendado, controla os filtros referentes a um campo, na execução de relatórios.Em um formulário, monta um mapa com todos os conjuntos de registros temporários usados no processo.TempRecords<R extends Serializable>Este é o objeto que transporta os registros temporários entre o formulário e o banco de dados, e também entre o banco de dados e o processo agendado.