Em várias aplicações, geralmente é necessário implementar uma representação hierárquica de objetos. Normalmente, isso é usado para classificá-los especificando grupos. Esses grupos formam uma árvore de profundidade dinâmica, que é usada para navegação, agregação de dados e configuração de parâmetros.
Neste artigo, mostrarei como essa lógica pode ser implementada na plataforma
lsFusion aberta e gratuita.
Como exemplo, vamos usar uma lógica simples na qual é necessário implementar a lógica de mercadorias agrupadas em grupos específicos que formam uma hierarquia de profundidade dinâmica. Nesse caso, as mercadorias podem ser vinculadas a um nó intermediário da árvore.
Primeiro, de acordo com o esquema padrão, declare a entidade do
grupo de produtos como uma classe simples e plana, com formulários de edição e uma lista:
Agora vamos criar uma hierarquia de grupos. Para fazer isso, apresentamos uma propriedade que conterá um link para o grupo pai:
Em seguida, criamos uma propriedade que determinará recursivamente o relacionamento entre dois grupos:
Em que princípio o operador
RECURSION funciona , não descreverei neste artigo, mas a propriedade
level retornará 2 ao grau de "comprimento do caminho entre
filho e
pai na árvore direcional correspondente".
MATERIALIZED indica que a plataforma deve armazená-la em uma tabela separada, onde para cada par de nós conectados haverá um registro separado com o valor do
nível na coluna correspondente. Com qualquer alteração na estrutura da árvore, esta tabela será recontada automaticamente.
Por exemplo, para uma árvore assim:
A tabela ficará assim:
Nele,
key0 é o código descendente e
key1 é o código pai. O número de entradas nesta tabela será aproximadamente igual ao número de grupos vezes a profundidade média da árvore. Esse esquema de armazenamento será útil, pois se você precisar contar todos os descendentes do grupo, não precisará recorrer a solicitações de CTE, mas poderá usar o JOIN usual para esta tabela.
Além disso, com base na propriedade construída, o nome canônico do grupo pode ser calculado:
Por exemplo, para o grupo
Milk na figura acima, o nome canônico seria
All / Groceries / Dairy / Milk .
CHARWIDTH é especificado para informar à plataforma qual largura usar para esta propriedade (em caracteres) ao criar a interface.
Agora vamos expandir o formulário para visualizar e editar grupos com propriedades recém-criadas:
Um formulário com uma lista de grupos em um formulário simples terá a seguinte aparência:

Depois que a lógica dos grupos for concluída, adicione a entidade
Product :
Crie um link de produto para o grupo de produtos ao qual ele pertence:
Por fim, criaremos um formulário para entrada de mercadorias, no qual haverá dois elementos: uma árvore de grupos e uma lista de mercadorias. Para o grupo de árvores selecionado, apenas os produtos que pertencem a qualquer descendente do nó selecionado serão exibidos na lista. Primeiro, declare um formulário e adicione uma árvore a ele com uma lista de grupos:
Usando o comando
TREE , uma árvore é criada a partir de objetos da classe
Group , cuja hierarquia é determinada pela propriedade
pai criada anteriormente.
Adicione o formulário ao navegador:
Neste exemplo, a entrada e a edição de mercadorias serão realizadas não por meio de diálogos separados, mas diretamente no próprio formulário. Para fazer isso, crie uma ação para criar um produto com referência ao grupo selecionado:
Agora, no formulário criado anteriormente, adicione a lista de produtos com colunas editáveis:
Use os botões do formulário para adicionar e remover mercadorias:
Como a ação
newProduct é definida para um grupo de produtos, é necessário especificar explicitamente que ela deve ser adicionada à barra de ferramentas com a lista de produtos (p).
Resta configurar o design para que a árvore seja exibida à esquerda e a lista de produtos à direita e entre eles haja um separador, com o qual você pode redimensionar objetos:
O formulário final ficará assim:

Após a criação da hierarquia de produtos e grupos, geralmente é necessário definir algum parâmetro em qualquer um dos níveis. Além disso, quanto menor a hierarquia for especificada, maior será o seu valor. Por exemplo, se o grupo
Laticínios estiver definido como 30 e o grupo
Leite estiver definido como 20, o último deverá ser selecionado.
Suponha que você queira definir a opção
premium dessa maneira. Para fazer isso, primeiro crie a propriedade apropriada para o grupo:
Para encontrar o valor desejado, basta usar o agrupamento com a escolha do último valor:
Traduzida para o idioma comum, essa expressão encontra (
GROUP ) a última
marcação (
LAST ) no grupo superior (
pai do grupo ), em ordem decrescente de distância a ele (
nível de ORDER DESC (filho, pai) ), para o qual essa marcação fornecido (
marcação WHERE (pai) ). Aqui, quero observar como lsFusion corresponde à linguagem natural.
Adicione as propriedades criadas acima ao formulário do produto na árvore de grupos:
Suponha que exista uma necessidade de definir um prêmio diretamente para um produto e que ele seja maior que o prêmio do grupo. Para fazer isso, primeiro crie a propriedade principal do produto:
Em seguida, declaramos uma propriedade que retornará o prêmio do produto, se um for especificado, ou o prêmio do grupo:
Depois disso, adicione as duas propriedades ao formulário:
O mecanismo para definir prêmios para grupos e produtos terá a seguinte aparência:

Conclusão
No artigo acima, fomos capazes de criar a lógica dos produtos, combiná-los em grupos com uma hierarquia de profundidade dinâmica e também fornecer ao usuário a capacidade de definir prêmios em qualquer nível. Tudo isso levou cerca de 70 linhas de código significativas. Você pode tentar como funciona on-line, bem como fazer alterações no código na
seção apropriada
do site (guia Plataforma). Aqui está todo o código-fonte que você precisa colar no campo apropriado:
O modelo descrito acima pode ser modificado e usado de várias maneiras, adicionando parâmetros adicionais às propriedades. Por exemplo, em uma implementação do
sistema ERP, os prêmios para grupos e mercadorias são definidos dessa maneira não globalmente, mas separadamente para cada tipo de preço. Além disso, a implementação em complexidade não é diferente do exemplo descrito acima.