Curso GeneXus X Ev2: Ejercicios prácticos

Documentos relacionados
Exercícios práticos. GeneXus 15

Cursos GeneXus - Carregando os tipos de dados estruturados

Curso Genexus - Introdução a Web Panels

Relações entre os atores da realidade

Curso GeneXus - Comunicação entre Objetos

Identificando atributos disponíveis

Verificação da instalação do GeneXus 15. Como verificar se o GeneXus 15 tm está instalado corretamente

Curso GeneXus - Fazendo crescer a aplicação

Curso GeneXus - Atualização do banco de dados - Business Components

Trabalhando com documentos

Administrando as bases de conhecimento (GXserver)

TRABALHO FINAL 20 Pontos

Curso GeneXus - Otro ejemplo de uso de Business components

Criação da Base de Conhecimento

Fixo (41) Vivo (41) Tim (41) Claro (41) OI (41) Sistema Descomplicado CNPJ

Delphi 7 Aula 03 Progressão Geométrica

Banco de Dados. -Aprendendo conceitos -Usando o SQL Conf para: -Conectar no banco de dados -Criar, alterar, excluir e consultar estruturas de tabelas

Sibele Loss Edimara Heis

Executar uma macro clicando em um botão da Barra de Ferramentas de Acesso Rápido

Painel Administrativo Westlock

Gerabyte AFV (Automação de Força de Venda) Manual do Aplicativo

Tutorial rápido CMAP TOOLS

Manual de Instruções. Cadastro de Contribuinte e Configuração de usuário para emissão de NFS-e. SapiturISSQN Versão 1.0 1

UNIVERSIDADE FEDERAL DO AMAPÁ PRÓ REITORIA DE ADMINISTRAÇÃO E PLANEJAMENTO DEPARTAMENTO DE INFORMÁTICA. Manual do Moodle- Sala virtual Aluno

Manual Site Unidéias.Net

Microsoft Word 2010 NORMA ABNT para Trabalhos Acadêmicos Conceitos Básicos

TUTORIAL UTILIZAÇÃO XOOPS UEFS. AEI - Gerência de Suporte

SRM RELAÇÃO COM OS FORNECEDORES MANUAL DO FORNECEDOR. Junho Versão 2

Aula 01 Microsoft Excel 2016

Manual MAZK (Professor)

Sumário 1. Perfil Fórum Tarefa Wiki Glossário Mensagem Privada Notas...

Usando o Eclipse - Fundamentos. Professor Vicente Paulo de Camargo

Criando uma página de Recados com acesso restrito ( Facebook )

Outlook Web App (OWA)

QUESTIONÁRIO. Você encontrará neste tutorial os seguintes tópicos: COMO CRIAR UM QUESTIONÁRIO

5.9 Mídias: Clique no botão de Gerenciador de Mídias, ou acesse o Menu Conteúdo => Gerenciador de Mídias.

Os arquivos podem conter qualquer tipo de informação: Texto Sons (Músicas) Imagens (Fotos, etc.) Vídeos E podem ser Programas de Computador

Curso GeneXus Criação da Base de Conhecimento

MANUAL DO PROFESSOR AMBIENTE VIRTUAL DE APRENDIZAEGEM

S40. Primeiros Passos. DAELT - Profa. Mariana Antonia Aguiar Furucho e Prof. José da Silva Maia 1

Inserindo Imagem. Inserindo uma imagem a partir da Galeria

Vejamos agora as ferramentas mais utilizadas para criação de imagens:

9. ARQUIVOS E PASTAS 9.1 O QUE SÃO ARQUIVOS E PASTAS?

TUTORIAL DE INSTALAÇÃO E USO DO OWL-S COMPOSER utilizando o Eclipse Galileo Modelling Tools

PAINEL DE CONTROLE LANDS AGÊNCIA WEB. Assim que digitar este endereço e apertar enter, você será redirecionado para esta página:

MANUAL. Certificado de Origem Digital PERFIL PRODUTOR. Versão

SUBIR LISTAS DE S

Questionário de revisão para AV1 de Informática Aplicada Valor 1,0 ponto - Deverá ser entregue no dia da prova.

Gerabyte AFV (Automação de Força de Venda) Manual do Aplicativo

MANUAL. Localizador: Página: MN 016 SGI-INFRA- . Informação)

PROCEDIMENTO OPERACIONAL PADRÃO

SISGRAD para docentes

ALFACONT 2 Sistema de Contabilidade Versão Eleusmário Mariano Rabelo. Acesso ao Sistema

SGCD 2.0 Sistema Gerenciador de Conteúdo Dinâmico

SISTEMA ADM ERP - MANUAL DO USUÁRIO. Conceitos Básicos

Universidade de São Paulo

Bem-vindo ao Manual de Navegação do Portal do Fornecedor Vale.

Conhecendo e editando o seu perfil

Visual Studio+SQL Server Express LocalDB ANTONIO LUIS

Como criar o seu Servidor Metatrader5 na Nuvem (cloud) da Amazon

Manual do Portal da UFPE para Editores de Conteúdo Manual Publicadores de Conteúdo no Portal

SQL Server Integration Services

Manual Coleção Interativa Papel Professor Versão 2.5.3

Manual do Usuário Brother Meter Read Tool

b. Inserir espaço entre parágrafos layout da pagina setinhe caixa paragrafo Recuo Esq e Dir = zero espaçamento antes = 0, depois = 10

PDV - Controle de Mesas

Criando site. Tutorial Webnode

Portal Educacional Professor On line

MANUAL DO PREPARA UPDATE VERSÃO

MANUAL. Localizador: SGI-INFRA-

Bem-vindo ao tópico sobre valores definidos pelo usuário.

Noções básicas do SAP Business One Tópico: Cadastro e documentos

Tutorial de Administração de sites do Portal C3

TICs IVINHEMA-MS

Módulo 03. Trabalhando com listas, imagens e tabelas

Instalação Serviço de Acompanhamento de Projeto (PCSIS007) Sistema de Gestão da Qualidade

Inserindo Quebra de Página

1 Instalar navegador Google Chrome através deste link (clique)

Tutorial para atualização de notícias/blog

Execute o instalador atiecli5 clicando duas vezes sobre o mesmo e será apresentada a tela inicial:

TUTORIAL DE INSTALAÇÃO E USO DO OWL-S COMPOSER 3.0 utilizando o Eclipse Galileo Modelling Tools

Soluções Integradas em Sistemas e Monitoramento. Manual do Administrativo do Cliente

Para abrir um documento deve utilizar uma das abordagens seguintes.

Configuração do Gmail para administradores

Na seqüência, será aberta uma página de login de acesso ao ambiente de gerenciamento do portal, conforme ilustrado na figura 01, abaixo: Figura 01

MANUAL DO SISTEMA FLEXISS PARA ACESSO DE ENTIDADES

O que é e como funciona o VBA no excel?

Criando Mensagens - Editor Drag and Drop

MANUAL DE PUBLICAÇÃO NO PORTAL CAMPUS MATÃO

GUIA RÁPIDO. MDIForms. Sintel Informática Ltda. Rua Vergueiro, nº º andar Vila Mariana, São Paulo - SP CEP:

Versão 8.3A-01. Versão Final da Apostila de Novidades

Transcrição:

Copyright Artech Consultores S. R. L. 1988-2013. Todos os direitos reservados. Este documento não pode ser reproduzido em nenhum meio sem o consentimento explícito de Artech Consultores S.R.L. A informação contida neste documento é exclusivamente para uso pessoal. Marcas Registradas Artech e GeneXus são marcas registradas de Artech Consultores S.R.L. Todas as demais marcas mencionadas neste documento são propriedade de seus respectivos donos. Página 1

1. O PROBLEMA... 3 2. NOVO PROJETO, NOVA BASE DE CONHECIMENTO... 3 3. PRIMEIRAS TRANSAÇÕES... 3 TRANSAÇÃO CUSTOMER... 4 TRANSAÇÕES ATTRACTION E COUNTRY RELACIONADAS... 7 Dados relacionados: como se mantém a integridade?... 10 TRANSAÇÃO CATEGORY... 10 ACRESCENTEMOS AS CIDADES À TRANSAÇÃO COUNTRY... 13 TRANSAÇÃO ATTRACTION : ACRESCENTEMOS A CIDADE.... 14 4. ADICIONEMOS COMPORTAMENTOS ÀS TRANSAÇÕES (PAPÉIS)... 15 5. PATTERNS: MELHORANDO A INTERFACE PARA TRABALLHAR COM A INFORMAÇÃO... 16 6. LISTAS PDF... 19 7. TRANSAÇÕES FLIGHT E AIRPORT E NECESSIDADE DE DEFINIR SUBTIPOS... 21 8. FÓRMULAS... 22 9. BUSINESS COMPONENTS... 24 AUMENTO DO PREÇO DOS VOOS... 24 TELA PARA ELIMINAÇÃO DE TODOS OS VOOS... 26 10. PROCEDIMENTOS PARA ATUALIZAR REGISTROS... 27 AUMENTO DE PREÇOS DOS VOOS... 27 EXCLUSÃO DE TODOS OS VOOS... 27 INICIALIZAÇÃO DA INFORMAÇÃO DO BANCO DE DADOS [OPCIONAL]... 29 11. PASAGEM DE PARÂMETROS... 30 LISTA DE ATRAÇÕES EM UM GRUPO DETERMINADO... 31 12. WEB PANELS... 32 13. VARIÁVEL DE TIPO DE DADO ESTRUTURADO, DATA PROVIDER PARA CARREGÁ-LA E WEB PANEL PARA MOSTRÁ-LA... 36 14. EXTENDED CONTROLS... 38 15. OBJETO QUERY... 39 16. GXSERVER... 40 17. DEFINIÇÃO DE UM MODELO DE PROCESSO DE NEGÓCIOS (BPM) PARA A RESERVA DE UMA ATRAÇÃO... 41 18. TESTAR O APLICATIVO COM GXTEST... 43 19. PRECISA-SE DE UMA PARTE PARA SMART DEVICES... 45 Página 2

1. O problema Uma agência de viagens contrata você para desenvolver um sistema para armazenar e manipular a informação com a qual trabalha. Imagine que o sistema é composto de dois módulos: Backend: parte do aplicativo que deverá rodar em um servidor web, de tal modo que os funcionários da agência possam manipular a informação de qualquer lugar com conexão à internet. É privada, por isso deverá ter segurança. Frontend: parte do aplicativo que implementará o site da agência. Será pública, utilizada por qualquer pessoa que queira fazer consultas sobre viagens, destinos, atrações turísticas etc. Nesta atividade prática, implementaremos apenas uma parte da solução para este problema. O que devemos fazer primeiro? 2. Novo projeto, nova base de conhecimento Entrar em GeneXus e criar uma nova base de conhecimento com o nome TravelAgency para começar o desenvolvimento do aplicativo. Sugerimos: Escolher como ambiente de desenvolvimento C#. Tenha certeza de que instalou tudo o que é necessário (incluindo SQL Server). Não criar a base de conhecimento na pasta Meus documentos ou qualquer outra pasta que fique dentro de Documents and Settings, porque essas pastas têm permissões especiais dadas pelo Windows. Use alguns minutos para familiarizar-se com o IDE (ambiente de desenvolvimento integrado de GeneXus). Teste mexer as janelas, visualizar as janelas específicas que deseja (View e View/ Other Tools Windows) e observe com atenção o Folder View dentro da janela Knowledge Base Navigator. Você verá que aparecem já inicializados domínios, alguns objetos, imagens, etc. Sugestão: mantenha a janela propriedades aberta (F4), pois você a utilizará continuamente. Dentro da janela Knowledge Base Navigator observe a seção Preferences, onde se configura o Environment. 3. Primeiras transações Nas reuniões com a agência de viagens, disseram o seguinte: Nós registramos os dados de nossos clientes e lhe oferecemos viagens a distintas cidades de distintos países, das quais também registramos as atrações turísticas. Para começar a construir o aplicativo, devemos começar identificando as entidades da realidade e representá-las por meio de transações. Quais transações devemos criar na base de conhecimento (KB)? Página 3

Transação Customer Perguntamos aos funcionários da agência de viagens: quais informações de seus clientes são registradas? Sabendo que a resposta é O nome (que não supera 20 caracteres), sobrenome (que também não supera), endereço, telefone e e-mail. Você já pode criar a transação Customer. É preciso lembrar que: Existem várias alternativas para criar objetos: o Partindo-se da página Start Page. o Do menu: File/ New Object o Ctrl+N Será preciso um atributo que identifique cada cliente (CustomerId). Digitando ponto (. ) quando for inserir um novo atributo, este se inicializa com o nome da transação. Adress, Phone e Email são domínios semânticos que se atribuem automaticamente aos atributos que se definem contendo em seu nome os textos Adress, Phone e o Email respectivamente. A estrutura da transação deveria ter ficado como se vê abaixo (ao lado, seu form web): O próximo passo é testar o aplicativo em execução. Confira se a janela Output de GeneXus está habilitada e à vista. (View/ Other Tool Windows/ Output) Agora sim, teste o aplicativo em execução pressionando F5. O que acontecerá? Página 4

Solução Se você decidir criar o banco de dados e programas localmente (isso só é possível com GeneXus full), será aberta uma janela como a seguinte para insirir a informação do Banco de Dados, Servidor e método de conexão. Lembre-se que, se não existir um banco de dados com o nome que você indicou nesse servidor, GeneXus o cria. Se, em vez disso, o banco de dados e os programas forem criados na nuvem, a caixa de diálogo anterior não aparece, já que GeneXus conhece os dados do servidor na nuvem e configura automaticamente o nome do banco de dados e toda a informação de conexão com ele. Em seguida, abre-se uma Análise de Impacto que detalha que se criará o banco de dados a tabela CUSTOMER dentro dela: Página 5

Se você pressionar o botão Create, GeneXus executará o programa que executará essas criações. Ao finalizar o processo, o menu com os links para executar os objetos definidos é aberto no navegador que tiver sido configurado como pré-determinado. Neste caso, apenas um: a transação Customer. Insira alguns clientes no sistema. Modifique algum dado de algum dos clientes inseridos anteriormente e exclua outro cliente. Também teste selecionar um cliente da lista de seleção (entre os ícones que aparecem destacados na imagem a seguir, está a imagem de uma lupa). Página 6

Agora, passemos a identificar e a criar a transação seguinte. Lembremos o que nos foi dito: Nós registramos os dados de nossos clientes e lhes oferecemos viagens a distintas cidades de diferentes países, das quais registramos também as atrações turísticas. Transações Attraction e Country relacionadas Agora, vamos criar uma transação para registrar as atrações turísticas e outra para registrar os países aos quais essas atrações pertencem. Que informação a agência de viagens maneja de cada atração? Nome, país, imagem da atração, categoria a que pertence. As atrações já podem ser criadas. Comecemos por Country : Lembre-se que: clicando-se sobre a tecla ponto (. ) quando estiver por dar um nome a um atributo na estrutura da transação, aparece inicializado com o nome da transação. você precisará de um atributo identificador, CountryId. Quando estiver definindo o tipo de dado do atributo identificador, em vez de utilizar diretamente Numeric(4.0), defina o domínio Id com esse tipo de dado. Configure a propriedade Autonumber desse domínio em True para que todos os atributos baseados nele se numerem automaticamente sem que o usuário precise se preocupar. Solução Página 7

Observe todos os domínios que já vem pré-definidos em GeneXus, em particular Addres, Email e Phone, que tinham aparecido automaticamente quando foram criados os atributos CustomerAddress, CustomerEMail e CustomerPhone na transação Customer. Defina o atributo CountryName, com tipo de dado, um novo domínio: Name=Character(50). Agora, vamos criar a transação Attraction. Por ora, insira somente o identificador, o nome e o país. Observe que ao inserir AttractionId, automaticamente assume o domínio Id. De modo semelhante, quando inserir o atributo AttractionName, assumirá automaticamente o domínio Name. Por que, além de CountryId, o atributo CountryName foi colocado em Attraction? Página 8

Execute para testar. F5. Aparecerá o seguinte relatório de Análise de Impacto. Por que na tabela Atttraction que GeneXus informa que se deve criar no Banco de Dados não aparece o atributo CountryName? Isto é, por que a tabela física não o conterá, sendo que está na estrutura da transação? Depois de estudar o relatório, se estivermos de acordo, pressionamos Reorganize para que efetivamente se execute o que se informa. Abre-se o navegador com o menu com os links aos 3 programas que correspondem a cada uma das transações ( Customer, Country e Attraction ). Inserir como países: Brasil, França e China. Observar que deixando 0 como valor do identificador, ao gravar, é atribuído automaticamente o número posterior ao último atribuído (efetivamente, se está autonumerando). Página 9

Inserir como atração turística: Louvre Museum, que está na França. Se você não se lembra qual é o identificador da França no sistema, como inserir o país? Lembre-se que é oferecida uma Lista de seleção de países, criada automaticamente por GeneXus e oferecida com um ícone especial, ao lado de CountryId. Isso acontece porque CountryId tem o papel chave estrangeira (foreign key), nesta transação (ou seja, está apontando para outra tabela). Dados relacionados: como se mantém a integridade? Attraction e Country estão relacionados. Ao colocar CountryId na estrutura de Attraction, por ter exatamente o mesmo nome que o atributo que é chave primária na transação Country, GeneXus entende que em Attraction CountryId é chave estrangeira e mantém automaticamente a integridade da informação. Assim, para exemplificar: Tente inserir uma atração com um id de um país que não exista. É possível salvar a atração turística? Escolha uma atração inserida anteriormente (Louvre Museum, por exemplo) e mude o país por outro que não exista. Conseguiu salvar a alteração? Tente excluir um país (usando a transação Country) que tenha alguma atração associada (França, por exemplo). Foi possível? Conclusão: os programas correpondentes às transações garantem a integridade dos dados. Transação Category Falta completar a informação da transação Attraction. Os funcionários da agência de viagens descreveram que registram de cada atração turística, a categoria (monumento, museu, parque etc) a que pertence. Assim, Página 10

necessitaremos criar uma transação para registrar essa informação e acrescentar a categoria à transação Attraction. Mas informaram também que não é obrigatório registrar a categoria da atração que uma dada atração que está se manipulando pertence. Pode deixá-la vazia. Se sabemos que GeneXus controla automaticamente a integridade, como o conseguimos? Solução: Para terminar a definição da transação Attraction, acrescentemos o dado que está faltando: a foto. Para isso, você deve criar o atributo AttractionPhoto do tipo de dado Image. Peça a GeneXus que construa o aplicativo, assim pode testá-lo em execução (F5). Observe o que o relatório de Análise de Impacto informa. Deverá ser criada a tabela Category e a tabela Attraction já existente deve ser convertida, acrescentando três elementos de informação (um pelo atributo CategoryId e dois pelo atributo AttractionPhoto. Não se preocupe em entender por que é preciso armazenar dois valores por imagem). Página 11

Reorganize e execute. Insira categorias (como museu e monumento) e acesse as transações turísticas já inseridas para completar sua informação (categoria e foto). Observe que neste caso é possível deixar a categoria vazia (porque a propriedade Nullable foi configurada em Yes na estrutura da transação). No entanto, se você tentar colocar como valor de CategoryId para a atração turística um valor inexistente, não será possível salvar. Página 12

Acrescentemos as cidades à transação Country Além dos países com os quais a agência de viagens trabalha, precisamos registrar a informação de suas cidades. Devemos, portanto, acrescentar um segundo nível à transação Country com o identificador e o nome da cidade. Lembre-se que: Posicionado no atributo CountryName, com o botão direito / Insert Level acrescenta o subnível. Uma vez que se dê um nome ao novo nível, digitando aspas ( ) em vez de ponto, o atributo definido incializará com o nome do nível. As cidades serão identificadas por seu próprio id em combinação com o do país. Ou seja, não poderá identificar uma cidade sem antes oferecer a informação do país de que se trata. Assim, poderia existir uma cidade 1 Rosário tanto para Uruguai como para Argentina. País: 1 (Uruguai) Cidade: 1 (Rosário) País: 2 (Argentina) Cidade: 1 (Rosário) Ou poderia ser inclusive que Rosário para Argentina se identificasse com outro número: País: 2 (Argentina) Cidade: 4 (Rosário) Reorganize e execute (F5). Página 13

Observe que a Lista de Navegação informará que: A propriedade autonumber para o caso de CityId será ignorada. Isso significa que, em execução, o usuário deverá inserir manualmente os identificadores da cidade. A explicação é que a propriedade Autonumber autonumera somente chaves primárias simples e, neste caso, CityId é o segundo componente de uma chave composta. Será criada uma nova tabela CountryCity para armazenar a informação correspondente às cidades. Insira cidades para os países que você já tinha registrado. Transação Attraction : acrescentemos a cidade. Na transação Attraction, acrescentemos a cidade do país a que a atração pertence. O que deve ser feito se a agência de viagens nos informar que esse valor pode não ser conhecido ou relevante para uma determinada atração em um dado momento? Construa o aplicativo e teste (F5 e Reorganize). Página 14

Solução Antes de seguir, abra a transação Customer e modifique o tipo de dado de CustomerId para que tenha domínio Id (e, assim, se autonumere). Também modifique os tipos de dados de CustomerName e CustomerLastName para que passem a assumir o domínio Name. Reorganize. 4. Adicionemos comportamentos às transações (papéis) Depois de testar com nós mesmos o aplicativo temos desenvolvido, nos contam na agência de viagens que, para os clientes, existe um comportamento específico que devemos fazer cumprir na hora de manipular a informação através do programa (transação Customer ). Que comportamento é esse? Eles nos dizem: O sistema deve permitir inserir clientes sem nome e sem sobrenome. O sistema deve advertir o usuário que está deixando o campo telefone sem preencher, já que pode ter sido um descuido. A data de entrada deve ser registrada no sistema (CustomerAddedDate) e deve-se propor como valor prédeterminado para este atributo a data de hoje. Especifique esse comportamento e teste-o (F5 e Reorganize). Lembre-se que: As regras terminam com um ponto-e-vírgula, ;. O método IsEmpty() aplicado a um atributo devolve True quando o atributo está vazio e False, em caso contrário. A variável %today é do sistema e tem o valor da data do dia carregado. Para escrever uma variável dentro da tela Rules, quando digitar & abrem todas as variáveis definidas até o momento para que selecione o que precisa. A outra possibilidade é utilizar Insert/ Variável. Página 15

Teste inserir um novo cliente deixando seu nome em branco. É permitido salvar ou passar ao campo seguinte? Faça o mesmo com o sobrenome. Acontece a mesma coisa com o telefone? Se depois informam que a data da entrada no sistema não deveria ser manipulado pelo usuário, mas apenas visualizada, como você estabelece esse comportamento? Especifique-o e teste em execução. 5. Patterns: melhorando a interface para traballhar com a informação Ao mostrar ao cliente o que foi feito até agora, ele nos diz que deseja manipular informação de países, categorias e atrações turísticas de um modo mais potente e vistoso (que ofereça consulta, possibilidade de filtrar, bem como inserir, alterar e excluir dados etc). Para isso, é preciso aplicar os padrões Work With às três transações. Teste e veja em execução. Observe que: Existe um Work With para Smart Devices também. Mas o que você deverá aplicar é o que corresponde ao aplicativo web que está construindo. GeneXus criará automaticamente vários objetos por transação para implementar o Trabalhar com essa entidade. Solução Página 16

Por que as transações Category, Country e Attraction não aparecem mais do Developer Menu? Teste: 1. Inserir um novo país; 2. Alterar um país existente (acrescentando uma cidade, por exemplo); 3. Excluir um país existente; 4. Visualizar a informação de um país; 5. Fazer uma busca por nome de país; Página 17

6. Inserir um par de transações turísticas (Por ex.: A muralha de China/ Pequim. Torre Eifell de França/ Paris); 7. Filtrar as atrações turísticas cujo nome começa com F. E se agora quiser poder visualizar todas as atrações turísticas da França? Essa possibilidade não está incluída, por mais que devamos personalizar o pattern work with dessa transação para acrescentá-la. Faça em GeneXus e teste em execução. Solução Para isso, primeiro, observe como está especificado que o filtro que existe, por nome da atração turística: 8. Agora, tire os identificadores de país e cidade da tela do Work With e teste-o em execução. Página 18

9. Se agora quiser oferecer a possibilidade que o usuário escolha ver as transações ordenadas por nome da atração ou por nome do país, implemente e faça o teste. 6. Listas pdf Agora, imaginemos que como parte do aplicativo, deverá ser implementada a possibilidade de que, a pedido do usuário, sejam abertas listas pdf com a informação solicitada. Por exemplo, suponha que se slicite uma lista pdf que mostre, em ordem alfabética, as atrações turísticas armazenadas no banco de dados. Sabe-se que deve ser mais ou menos como: Implemente em GeneXus. Página 19

Lembre-se que para poder visualizar uma lista diretamente do browser, ela deve ser gerada como PDF. Para isso, é preciso configurar as seguintes prorpriedades do objeto procedimento: Main program = True Call Protocol = http Report output = Only to File E a seguinte regra: Output_file( nombre-archivo.pdf, PDF ) Para executar a lista, clique com o botão direito sobre a guia do objeto / Run with this only Reparou no que informa a lista de navegação do procedimento? E se agora for preciso que a lista saia ordenada por nome de páis? Implemente isso, observe o que é informado na lista de navegação e faça o teste. E se agora for preciso apenas listas de atrações da França? Teste (observando a lista de navagação). Em cada caso, deduza qual tabela do banco de dados se está recorrendo para realizar a consulta do for each. Precisa-se também de uma lista como a que segue (que mostre cada categoria e, para cada uma delas, suas atrações turísticas). Implemente e teste o que foi feito. Página 20

Acrescente uma nova categoria ao sistema, Art Gallery (galeria de arte), por exemplo. Volte a executar a lista anterior. A categoria saiu na lista? Modifique a lista anterior para que não saiam nas listas as categorias que não tenham atrações turísticas relacionadas. Que modificações você encontrou na lista de navegação? 7. Transações Flight e Airport e necessidade de definir subtipos Agora, é preciso registrar os voos que a agência de viagens oferece. Cada voo tem um modificador e vai de um aeroporto a outro. Cada voo também tem um preço. Para o Preço crie um domínio Numeric(10.0). Crie uma transação para registrar os aeroportos. Cada aeroporto tem um identificador, um nome, um país e uma cidade na qual se encontra. Como é definido que cada voo tem um aeroporto de origem e outro aeroporto de destino? Lembre-se: 1) Que na estrutura da transação: Um ícone representando uma flecha para cima informa que o atributo é chave estrangeira (Foreign Key), ou seja, que aponta a outra tabela. Um ícone representando uma flecha para baixo informa que o atributo é inferido de outra tabela. Um ícone representando uma indica que o atributo é um subtipo. 2) Sobre os grupos de subtipos: Definem-se da mesma maneira que qualquer tipo de objeto. Cada grupo de subtipos deve conter obrigatoriamente um subtipo de um atributo primário (que é chave primária de uma tabela) ou conjuntos de atributos que formam uma chave primária. Página 21

Em cada grupo de subtipo, é preciso incluir todos os atributos subtipos que se deve conhecer, pertencentes à tabela base e/ou estendida da chave primária do grupo. Execute e verifique se ao tentar inserir um voo, é disparado um erro se o aeroporto de partida ao qual se está querendo atribuir ao voo não existe. Idem para o aeroporto de chegada. Não se deve permitir inserir um voo em cujo aeroporto de partida coincida com o aeroporto de chegada. Implemente esse comportamento e teste em execução. 8. Fórmulas É Preciso poder registrar o desconto atual que cada voo tem. Defina um novo atributo na transação Flight para armazenar esse dado. Dê ao novo atributo o nome FlightDiscountPercentage e defina que seu tipo de dado seja um domínio Percentage, numérico igual a 3. Deseja-se visualizar o preço final do voo com o desconto aplicado. Para resolver isso, defina outro atributo, chamado FlightFinalPrice, que seja fórmula global que calcule automaticamente o preço final do voo. Pressione F5, observe na Análise de Impacto qual atributo será criado fisicamente e qual não, reorganize e teste o aplicativo em funcionamento. Crie um segundo nível na transação Flight chamado Seat para registrar seus assentos. Posto que os assentos costumam ser identificados por um número e uma letra, a chave primária (ou o identificador único) do segundo nível deverá ser composta por 2 atributos: FlightSeatId: para registrar o número do assento FlightSeatChar: para inserir a letra Defina o domínio Seat Chat, do tipo character(1) com o objetivo que o atributo FlightSeatChar permaneça o mesmo. Restrinja que as letras possíveis de escolher para o domínio sejam de A a F (editando a propriedade Enum Values do mesmo). Página 22

Lembre-se que para definir que certo atributo é parte da chave primária, você deve pressionar o botão direito do mouse sobre o atributo e o menu contextual lhe oferecerá a opção Toggle Key. Para conhecer a capacidade de passageiros que o voo permite, crie um atributo novo no primeiro nível da transação Flight chamado FlightCapacity, tipo numeric(4), e defina-o fórmula global que conte a quantidade de assentos que o voo oferece. Deseja-se ver a capacidade do voo no formulário web e controlar que não se registre nenhum voo com menos de 4 assentos. Esse controle deverá ser feito quando terminar de inserir todos os assentos e depois de ter pressionado o botão Confirm. Outra solicitação da agência de viagens é uma lista que mostre todos os nomes de países e, para cada país, a quantidade de atrações turísticas que oferece: E nos pede outra lista que também mostre todos os países que tem mais de 2 atrações para visitar: Página 23

9. Business Components Realizaremos algumas operações sobre o banco de dados atrávés de business components. Aumento do preço dos voos Des tempos em tempos, a agência de viagens precisa aumentar os preços de voos em uma determinada porcentagem. Para isso, devemos implementar uma tela que permita ao usuário especificar essa porcentagem de aumento e dar a ordem de aplicá-la a todos os voos do banco de dados. Implemente e faça o teste. Lembre-se que: O objeto web panel permite implementar telas flexíveis para entrada e saída de informação. Para entrada de informação (que o usuário possa inserir valores na tela), se inserem controles variáveis no form. Se quiser editar barras de menu, posicionando-se em GeneXus acima sobre a barra, com o botão direito você poderá inserir, por exemplo, a barra Formatting. Para que a web panel tome alguma ação determinada, podem ser inseridos botões e programar o "evento" associado. Os business components são tipos de dados criados ao configurar a propriedade de nome Business Component do objeto de transação com valor Yes. Ao fazer isso, para inserir, modificar ou eliminar registros das tabelas correspodendentes, poderão ser utilizados, além da transação, uma variável de tipo de dado Business Components em qualquer outro objeto (por exemplo, uma web panel) e realizar as mesmas operações através dos métodos Load (), Save () e Delete (). Para que as operações realizadas através do business componentes fiquem efetuadas de maneira permanente, você deverá executar na sequência o comando Commint. Se a um valor X se quer incrementar em 20%, basta fazer X = X*(1+20/100) = X*1,20 Solução Uma solução possível (tente implementar o que foi pedido sem olhar o que vem a seguir): criamos uma Web Panel com uma variável &percentage, de tipo de dado Numeric(3.0) Página 24

Ao dar um clique duplo sobre o botão, somos levados à seção Events, editando o evento Enter, associado ao mesmo. Ali, programaremos a lógica que queremos que se execute quando o usuário pressionar o botão. Precisamos recorrer todos os voos e sobreescrever o preço que eles tinham, aumentando nessa porecentagem indicada pelo usuário na variável da tela. Para recorrer todos os voos do banco de dados, usamos o comando for each. E, para cada nvoo, como editamos para modificar seu valor de FlightPrice? Para isso, vamos precisar de uma variável que tenha toda a estrutura da transação Flight e, além disso, permita salvar no banco de dados. Que tipo de dados terá, então, essa variável? O business component Flight (observar que o tipo de dados business component tem o mesmo nome que a transação). Mas GeneXus não cria esse tipo de dado automaticamente para cada transação. Teremos que pedi-lo. Como fazemos? Ligando a propriedade correspodente da transação. Feito isso, logo: Event Enter for each &flight.load(flightid) &flight.flightprice = &flight.flightprice*(1+&percentage/100) &flight.save()... endfor EndEvent Como as operações para salvar ou exlcuir do banco de dados (através dos métodos Save() e Delete()) podem provocar erros, é importante saber o que aconteceu. Para isso, temos o método Sucess () que devolverá True se não houver erros e False, em caso contrário. Event Enter for each &flight.load(flightid) &flight.flightprice = &flight.flightprice*(1+&percentage/100) &flight.save() If &flight.success() Commit else Rollback endif endfor EndEvent Página 25

Ao inserir, modificar ou excluir regitros de uma tabela do banco de dados, enquanto não for dito que tudo o que foi feito fica permante, essas modificações serão provisórias. O que isso quer dizer? Que, por exemplo, se houver um apagão, essas modificações se perderão. A forma de dizer que fique permanente o que foi feito é executar o comando Commit. Se, ao contrário, quisermos que o que fizemos se desfaça, executamos o comando Rollback. Tela para eliminação de todos os voos Salve a web panel anterior com outro nome (para isso, basta posicionar-se sobe a aba e com botão direito, e clicar em Save as) e modifique o Form que contem apenas um botão com o texto "Delete all flights", de modo que em execução esta web panel se veja assim: Quando o usuário pressionar o botão, deverão ser eliminados todos os voos do banco de dados. O que deve ser modificado do evento Enter que estava programado? Nota: se se posicionar sobre o botão e vir suas propriedades, na de nome Caption você pode modificar o texto do botão. Solução Bastará: Event Enter for each &flight.load(flightid) &flight.delete() if &flight.success() Commit Msg( 'Successful deletion') else Msg( 'Deletion could not be done') Rollback endif endfor EndEvent Com Msg conseguirá que se abra essa mensagem na tela da web panel. Página 26

10. Procedimentos para atualizar registros Aumento de preços dos voos Imagine que chegam aos milhares os voos que devemos aumentar o preço em uma determinada porcentagem (volte ao primeiro exercício do ponto 9 dessa atividade prática). Sabendo que o aumento do preço é um procediemnto simples e que não vai fazer a integridade falhar de nenhuma maneira, faça como um procedimento, sem utilizar business component. Lembre-se que: Com o comando for each dentro de um procedimento, você pode atualizar os atributos de sua tabela estendida através de simples atribuições. A atualização direta através de procedimentos não controla a integridade da informação. Todo objeto deve declarar os parâmetros que recebe e os parâmetros que devolve. Se não os declara, não receberá, nem devolverá valores. Os parâmeteos são declarados através da regra parm. As variáveis são locais ao objeto onde são utilizadas. Isso significa que se eu quiser receber um valor como parâmetro em uma variável &X, devo declará-la no objeto. Exclusão de todos os voos E se agora você quisesse excluir todos os voos, como foi feito no ponto 9 dessa atividade prática, através de um procedimento? Solução Criar um procedimento FlightsDeletion, que não recebe parâmetros, com o seguinte código: for each defined by FlightPrice Delete endfor Faça um Save as da web panel que tinha implementado no ponto 9 (a que fazia a exclusão através de Business Component) e mude o evento Enter: Event Enter FlightsDeletion() EndEvent E se agora eu quiser apagar toda a informação do banco de dados? Página 27

Solução Criar um procedimento DeleteAll com Source: for each defined by CustomerName delete endfor for each defined by FlightPrice delete endfor for each defined by AttractionName delete endfor for each defined by CategoryName delete endfor for each defined by CountryName for each defined by CityName delete endfor delete endfor E mudar a web panel anteiror (save as), acrescentando um botão, ao qual associaremos um evento de usuário. Para isso, editando as propriedades do botão, em OnClickEvent, escolhemos <new> e damos o nome que quisermos: Página 28

Depois, clicando com o botão direito sobre o botão: Go To Event e programamos a invocação ao procediemnto. Inicialização da informação do banco de dados [opcional] Quando o aplicativo que você está desenvolvendo for posto em produção (ou seja, começar a ser utilizado pela agência de viagens) deverão ser carregados todos os dados dos clientes, países, categorias, atrações, voos. Escreva um procedimento que inicialize essas tabelas com informação que a agência de viagens tem nos dado e teste-o. Levar em conta que: O comando new insere um registro em uma tabela física. Se não atribuir valor a um atributo da tabela, logo: o Se o atributo for autonumerado, ao salvar o registro no banco de dados (ao alcançar o endnew ), para esse atributo, ficará na memória o valor dado pelo banco de dados a ele. Por exemplo, se estiver salvando uma categoria: New CategoryName = Monument Endnew Sabemos que depois do Endnew se utilizarmos o atributo CategoryId, ele terá o valor que o banco de dados deu ao registro ao inseri-lo. Solução Criar um procedimento DBInitialize com o Source a seguir e invocá-lo de uma web panel: new CustomerName = 'John' CustomerLastName = 'Cage' CustomerEMail = 'jcage@gmail.com' CustomerAddress = '11235 NE 4 Ave, Miami' endnew //Brazil new CountryName = 'Brazil' Página 29

endnew new CountryId = CountryId CityId = 1 CityName = 'Rio de Janeiro' endnew //France new CountryName = 'France' endnew new CountryId = CountryId CityId = 1 CityName = 'Paris' endnew new CategoryName = 'Monument' endnew new AttractionName = 'Eiffel Tower' CountryId = CountryId CityId = CityId CategoryId = CategoryId AttractionPhoto = EiffelTower.Link() endnew new CountryId = CountryId CityId = 2 CityName = 'Niza' endnew //China new CountryName = 'China' endnew new CountryId = CountryId CityId = 1 CityName = 'Beijing' endnew new CountryId = CountryId CityId = 2 CityName = 'Shangai' endnew 11. Pasagem de parâmetros Muitas vezes, precisamos que um objeto receba parâmetros para, baseados neles mesmos, executar sua lógica. Por exemplo, uma coisa é realizar uma lista pdf de todas as atrações turísticas do banco de dados, outra é realizar uma lista daquelas atrações cujo nome encontra-se dentro de uma determinada categoria. Página 30

Lista de atrações em um grupo determinado Salve com outro nome o procedimento que você tinha criado no ponto 6 para listar as atrações turísticas e, modifique-o para que agora somente liste aquelas cujo nome encontra-se dentro de um grupo recebido por parâmetro (o valor incial e o final do grupo serão os parâmetros recebidos). Implemente uma tela que peça os valores desse grupo ao usuário e invoque este objeto, passando esses valores por parâmetro. Teste em execução. Lembre-se que: Se você definir uma variável baseada em (based on) um atributo, ela ficará ligada ao tipo de dado do atributo, ou seja, se ele se modifica, o da variável também, de acordo com a mudança. As variáveis utilizadas para realizar uma inovação no objeto que chama e as utilizadas para declarar os parâmetros que se recebem no objeto chamado não tem porque coincidirem em nome, mas devem ter tipos de dados compatíveis. Solução: Ao procedimento, vamos chamá-lo AttractionFromTo, acrescentamos a regra parm (e definimos ambas as variáveis no procedimento): parm( in: &fromname, in: &toname ); E no seu Source: print Title print ColumnTitles for each where AttractionName>= &fromname where AttractionName <= &toname print Attractions endfor Depois, criamos uma web panel, na qual definimos duas variáveis que podem ser chamadas de qualquer maneira, por exemplo A e B, mas que devem ter como tipo de dado um compatível com o das variáveis %fromname e %toname. Por quê? Porque serão nessas variáveis que o usuário inserirá valores que no evento que programemos serão enviadas por parâmetros ao procedimento, assim: AttractionsFromTo( &A, &B) Página 31

12. Web panels A agência de viagens solicita uma página que lhes possibilite inserir um identificador de um cliente e, ao pressionar um botão, sejam visualizados os dados de tal cliente. Outro requisito solicitado pela agência de viagens é uma página que mostre todos os clientes. De cada cliente, deseja-se ver seu nome completo e endereço. Lembre-se que uma alternativa para ter o nome e sobrenome de cada cliente concatenados, como vemos acima, é definir um atributo fórmula global (atributo virtual não armazenado no banco de dados) cuja definição consista no atributo que armazena o sobrenome + espaço ou vírgula + atributo que armazena o nome. No segundo nível da transação "Flight", acrescente os atributos correspondentes ao identificador de cliente, sobrenome e nome, para poder atribuir a cada assento de um voo, um cliente. Configure a propriedade Nullable=Yes para CustomerId, assim poderão ficar assentos que não foram atribuídos a nenhum cliente. Pressione F5, observe a Análise de impacto e proceda com a reorganizção e execução. Atribua os clientes aos assentos dos voos. Página 32

A agência de viagens solicita uma página que mostre todos os clientes e, para cada um, a soma total de preços de seus voos associados. Para reslver isso, salve a última web panel criada (a que contem um grid) com outro nome de objeto. Exclua a coluna CustomerAddress do grid e, em seu lugar, defina e inclua uma variável. Como o cálculo solicitado para cada cliente não se encontra registrado em um atributo, você deverá calculá-lo. Lembre-se que o evento Load em uma web panel com tabela base é executado justamente antes de carregar cada linha no grid. Este evento é adequado para atribuir à variável o cálculo que devolve a soma dos preços dos voos de cada cliente que se está navegando e a ponto de carregar em uma linha no grid. Agora, acrescente uma variável que permita filtrar a informação aberta por sobrenome do cliente. Página 33

Acrescente debaixo do grid uma variável que mostre o total gasto por todos os clientes. Lembre-se de esvaziar a variável antes de começar a carregar o grid. Edite novamente as colunas do grid e acrescente uma nova variável chamada &FlightImage como coluna do grid com o objetivo de carregar uma imagem (por exemplo, a imagem de um avião) para cada linha em tal variável: Página 34

Não se esqueça de que é necessário inserir a imagem do avião na base de conhecimento. Associe à imagem uma ação para que ao clicar sobre ela, abra outra página (web panel) que mostre os voos relacionados ao cliente da linha. Crie a nova web panel que receba o identificador de um cliente (Customer Id) e mostre na mesma a informação de seus voos. Agora, faça as modificações necessárias para que em vez de abrir uma nova web panel ao clicar sobre a imagem, a informação relativa aos voos do cliente se visualize em outro grid dentro da mesma web panel: Página 35

13. Variável de Tipo de dado estruturado, Data Provider para carregá-la e Web Panel para mostrá-la Será preciso mostrar em tela as categorias de atrações turísticas, mostrando de cada uma: nome da categoria e quantidade de atrações turísticas dessa categoria e esse país, como se vê abaixo: Como ainda não aprendemos como realizar um cálculo, deixe o número de atrações turísticas com um valor prédefinido (em branco, por exemplo). Mais adiante, voltaremos sobre este ponto para completá-lo. Lembre-se que: O objeto Web Panel permite desenhar telas para múltiplos usos. Cada objeto GeneXus pode definir variáveis que serão espaços de memória reservados dentro do objeto para manter temporariamente certos valores enquanto o objeto está executando (e que logo se desfazem). As variáveis são um nome que se dá a um espaço de memória que se reserva. Para reservar esse espaço, deve ser especificado seu tipo de dado. Um caso particular é quando uma variável não é de um tipo de dado simples, mas estruturado (ali deverão ser reservadas várias posições de memória para armazenar cada um dos elementos do tipo de dado). Os tipos de dados estruturados podem ser coleções de tipos de dados. Os Data Providers são utilizados para carregar variáveis de tipos de dados estruturados (ou business components, como veremos a seguir, que também são estruturados). Tente implementar o que vimos antes por sua conta, sem ver o que se segue. Página 36

Solução Uma possível solução é criar um tipo de dado estruturado que representa uma coleção de categorias com a informação que se precisa (nome de categoria e quantidade de atrações turísticas correspondentes). Depois, um Data Provider que permita carregar uma variável desse tipo, obtendo o nome de categoria do banco de dados. Para especificar seu Source, lembre-se que o mais fácil é arrastar o SDT do Folder View e soltá-lo na tela Source. Assim, terá que preencher somente o que se mostra em verde. Por agora, deixaremos vazio o valor de CategoryAttractions. Observemos que na propriedade Output, aparece o SDT que é coleção, motivo pelo qual a propriedade Collection está em False (se se pusesse em True, o resultado seria uma coleção de coleções). Depois, crie a Web Panel, definindo a variável &categories do tipo de dado do SDT anterior e inseri-a no Form. Será oferecido inseri-la dentro de um control Grid. Você deverá carregá-la, mas como? No evento Start, invocando o Data Provider anterior. Página 37

Event Start &categories = GetCategories() EndEvent 14. Extended controls Utilizando o extended control ImageGallery, crie uma web panel que mostre a galeria de fotos de todas as atrações turísticas. Personalize as propriedades do extended control, estabelecendo Width=1000, Height= 500, y Type=Slider: Página 38

15. Objeto Query Defina um objeto Query que devolva somente as cidades da França, ordenadas por ordem alfabética, cada uma delas com sua respectiva quantidade de atrações turísticas. Defina uma web panel e, utilizando o control QueryViewer, visualize a consulta anterior como um gráfico. Página 39

16. GXserver Publique a base de conhecimento no servidor http://sandbox.genexusserver.com/xev2/main.aspx Crie uma nova web panel (WPCustomers) que mostre a lista de clientes da Agência. Envie esse novo objeto ao servidor para que se integre à base de conhecimento centralizada. Entre no console web verifique o estado final da KB. Cierre la base de conocimiento anterior, y cree una nueva sincronizándose con la KB previamente publicada. De esta forma se recibe localmente una copia de la KB administrada por GXserver. Página 40

Nesta nova cópia local, edite a transação Country e defina o novo atributo CountryFlagImage, do tipo Image. Envie essa alteração ao servidor. Feche essa KB e abra novamente a KB inicial. Realize a operção Update para receber a alteração realizada antes. 17. Definição de um modelo de processo de negócios (BPM) para a reserva de uma atração O processo de reserva de uma atração turística consiste em uma série de tarefas que pode ser considerada como um processo de negócio. Este processo começa quando uma pessoa vai à agência de viagens reservar um pacote turístico para uma determinada atração. A primeira coisa que o funcionário da agência deve fazer é inserir uma reserva para tal pacote. Depois de inserida a reserva, é preciso verificar se a pessoa que solicita o pacote é um cliente da agência e, caso não seja, deverá inseri-la como cliente e associar tal cliente à reserva. Feitos esses passos, é preciso verificar se existem pacotes disponíveis para a quantidade de pessoas que desejam fazer a viagem. Se houver lugares disponíveis, a reserva será feita e o processo de negócios é finalizado. Se não houver lugares disponíveis, deve ser oferecido outro pacote ao passageiro. Para implementar o modelo, você deverá criar um objeto Business Process Diagram, mas antes deve criar uma transação Reservation com os seguintes atributos: ReservationId - Id ReservationDate - Date ReservationQty N(4) CustomerId Página 41

CustomerName ReservationAvailable Boolean O atributo ReservationAvailable é utilizado para marcar se o pacote turístico está ou não disponível. Para o atributo CustomerId, selecionamos sua coluna Nullable com o valor Yes, para indicar que no momento de inserir uma reserva, podemos não ter ainda o identificador de cliente, da pessoa que está adquirindo a reserva. Defina o modelo de negócios para a reserva de uma atração turística e execute-o, testando todos os casos mencionados na descrição, de forma a recorrer todo o diagrama. Solução Crie a transação Reservation, de acordo com o foi solicitado. Crie um objeto Business Diagram e nomeie-o AttractionReservation. Da barra de ferramentas, arraste ao diagrama um símbolo de NoneStartEvent. Localize a transação Reservation na janela de Folder Vier e arraste-a até o diagrama. Para conectar o nó de Start com a transação, clique na parte inferior do círculo verde e, sem soltar, arraste a conexão até que a ponta da flecha toque a margem superor do retângulo da transação. Para representar a decisão no diagrama para verificar se a pessoa é cliente da empresa, arraste um nó Exlcusive Gateway sobre o diagrama e una-o partindo da transação Reservation. Agora, deve-se definir a condição do Gateway que fará com que o fluxo siga o curso normal (para baixo) quando não é preciso que acrescentar a pessoa como cliente, ou o fluxo alternativo (para a direita), quando a pessoa deve ser inserida como cliente. Primeiro, arraste a transação Customer ao digrama e conecte-a à direita do Gateway. Depois, dê um duplo clique na flecha verde que une o Gateway com a transação Customer e escreva a expressão Reservation.CustomerId = 0 para indicar que o fluxo deve tomar esse caminho se, quando se inseriu a reserva, o atributo CustomerId deixou com o valor 0. Para associar o cliente recém-criado à reserva, você deve criar um procedimento chamado AssignCustomerToReservation e, na seção de regras, escreva uma regra parm com os parâmetros &ReservationId y &CustomerId. No source do mesmo, escreva um For each com uma cláusula Where filtrando o atributo ReservationId pela variável ReservationId recebida por parâmetro. Depois, atribua a CustomerId o valor da variável &CustomerId e feche o For each. Desta forma, designará ao cliete recém-criado a reserva inserida anteriormente. Agora, arraste o procedimento recém-criado até o diagrama e conecte-o partindo da transação Customer. Contiuando com o fluxo habitual (para baixo do Gateway), você deve contar com uma tela onde se possa confimar ou cancelar a reserva. Para isso, pode utilizar novamente a transação Reservation e se marcará a reserva como disponível ou não, por meio do atributo ReservationAvailable. Arraste a transação Reservation da janela de Folder View até o digrama. Renomeie a tarefa como ReservationAvailabity e conectea do Gateway. Para indicar que o fluxo para baixo é o fluxo normal, selecione a conexão e na janela Propriedades atribua a propriedade ConditionType no valor Default. Observe no digrama que o fluxo ficou assinalado com uma linha de cor verde que o cruza. Aproveite agora para conectar a tarefa AssigntCustomerToReservation à tarefa ReservationAvailability. Para avaliar o valor inserido na caixa de selação da transação Reservation, insira da caixa de ferramentas um Exlcusive Gateway e conecte-o da tarefa ReservationAvailability. Depois, conecte o fluxo alternativo do mesmo (que desenhamos para a esquerda) à tarefa Reservation para que se possa acrescentar uma reserva nova. Página 42

O que falta fazer agora é levar em conta o caso de que a reserva se confirme, quando já não haverá mais tarefas e o processo deverá ser finalizado. Para indicar que o diagrama deve terminar, insira da caixa de ferramenta um símbolo de NoneEndEvent e conecte-o do Gateway. Essa conexão para baixo é o fluxo normal do Gateway, de modo que quando a reserva se confirmar, o processo se finalizará. Para indicar isso, selecione a conexão e, na janela Propriedades, atribua a propriedade ConditionType com o valro Default. Agora, você deve executar o diagrama. Sobre a aba com o nome do diagrama, clique com o botão direito e escolha Run. Se abrirá uma tela com o Cliente GXflow. Selecione a tarefa Reservation e, para executá-la, pressione o botão de Execute ou dê um duplo clique sobre a tarefa. Insira uma reserva, deixando sem inserir o identificador do cliente. Pressione Confirmar e feche a janela. Para passar à tarefa seguinte, pressione Send. Como não o cliente não foi inserido, a próxima tarefa pendente é a transação Customer. Execute a tarefa e insira a pessoa que solicitou a reserva como cliente. Feche a janela e pressione Send. Observe que a próxima tarefa é ReservationAvailability, já que a tarefa AssignCustomerToReservation é não interativa e, portanto, se executou em forma batch. Execute a tarefa, amrque a caixa de seleção e pressione Confirmar. Feche a janela e pressione Send. Note que agora a caixa de entrada está vazia, indicando que não existem mais tarefas pendentes para executar, já que se chegou ao fim do processo. Execute novamente o diagrama, mas agora teste os outros caminhos do diagrama, inserindo, por exemplo, um identificador de cliente na transação Reservation ou deixando desmarcarda a caixa de seleção ao confirmar a reserva. Para ver o histórico das tarefas executadas, selecione My Process na janela Navigator e dê um clique duplo sobre o Processo AttractionReservation na janela da direita. Você poderá ver em uma janela todas as tarefas que se foram executando. Para ver o histórico em forma de animação, selecione More Actions, View Diagram e pressione o botão de Play. 18. Testar o aplicativo com GXtest GXtest permite salvar sequências de operações para testar novas telas e, verificar ante novas mudanças, que o sistema continue funcionando corretamente. Neste caso, vamos verificar se o preço de um voo se calcula sem erros. Este preço é representado pelo atributo FlightFinalPrice definido com uma fórmula global. Esta fórmula atribui o maior desconto possível, ou seja, se o desconto da empresa aérea é maior, toma-se tal desconto e caso contrário, toma-se o desconto do voo. Utilizando GXtest, defina um caso de teste inserindo um voo com os seguintes valores: País de partida: 1 Cidade de partida: 1 País de destino: 2 Cidade de destino: 1 Preço do voo: 5000 Desconto do voo: 50% Empresa aérea: 1 (desconto da empresa aérea: 30%) O preço calculado do voo será de 2.500, já que como o desconto de voo (50%) é maior que o desconto da empresa aérea (30%), se designará ao preço do voo um desconto de 50%. Cotinuando com o exemplo, insira um par de assentos para o voo e não pressione Confirmar. Página 43

Defina em GXtest que o valor correto para o texto que mostra o valor do preço do voo é de 2.500. Pressione Confirmar e feche o navegador. Verifique em GXtest que o caso de teste tenha sido criado corretamente. Verifique que tenha sido criado o pool de dados com os valores inseridos. Depois, mude a fórmula do atributo FlighFinalPrice (por exemplo, mude o 100 do segundo quociente, pelo valor 10) e execute o caso de teste inserido anteriormente. Verifique se GXtest informa que encontrou um erro e veja o valor calculado incorretamente na tela da transação Flight, que se mostra à venda de resultados do caso de teste. Depois, corrija a fórmula (colocando o valor de 100 em vez de 10) e execute novamente o caso de teste. Verifique que neste caso, GXtest não encontra erros e o resultado de teste mostra o valor do preço do voo calculado corretamente. Solução Abra o aplicativo GXtest Designer, do acesso direto na aérea de trabalho. Crie um projeto novo lhe dê um nome. Agora pressione o signo de mais (cor verde), escolha sua KB da pasta em que está armazenada, acrescente uma descrição e pressione OK. Quando finalizar a importação de dados da KB, pressione OK. A URL que GXtest nos solicita é o aplicativo a testar. Volte a GeneXus, excute a transação Flight, copie a URL do mesmo e cole no campo URL da janela de GXtest. Pressione OK. Na parte direita da janela do Designer de GXtest, pressione o botão direito sobre Test Cases e escolha Record Test Case. Atribua um nome ao caso de test, uma breve descrição e marque a opção para que se autogenere o conjunto de dados de teste. Pressione o botão vermelho na parte superior direita da janela. Você notará que se abrirá o navegador e se executará a transação Flight. Insira um novo voo com os dados especificados na letra do exercíco, incluindo um par de assentos, mas não pressione Confirmar para terminar de inserir o voo. Antes, selecione com o mouse o preço do voo (que mostra o valor 2.500) e pressione o símbolo de check na barra de ferramientas de GXtest de navegador. Escolha VerifyControlRest e acrescente uma descrição. Pressione Aceitar e novamente Aceitar. GXtest avisará que acrescentou corretamente a validação solicitada. Pressione OK. Volte à tela da transação Flight e pressione Confirmar. Feche o navegador e volte ao designer de GXtest. Veja que foi criado um caso de teste. No diagrama, selecione o componente chamado Flight e veja que na janela de comandos foram detalhados todos os passos realizados ao inserir o voo na transação Flight. No panel de Project, à direita da tela e sob DataPools clique no elemento do conjunto de dados. Verifique em tal janela os dados utilizados para inserir o voo. Volte a GeneXus, edite a fórmula do atributo FilghtFinalPrice e, na segunda divisão, escreva 10 em vez de 100. Pressione F5 para atualizar o aplicativo. Para executar o caso do teste definido, volte a GXtest, selecione a guia do caso de teste e pressione o botão de Play, que se encontra em cima, à esquerda da tela. Você verá que uma janela do navegador foi aberta, e é visualizada a tela da transação Flight e começa a execução automática do caso de teste, inserindo-se automaticamente os mesmos dados que você tinha inserido antes, como se fosse uma pessoa que fosse fazendo. Preste atenção aos valores e veja que o preço do voo foi calculado incorretamente. Agora, mostra o valor 20.000. Quando finalizar o caso de teste, notará que a janela do Designer de GXtest é ativada automaticamente. Abra o designer. Você verá que foi acrescentada uma guia com os resultados do test. Na coluna Result encontrará o símbolo de um inseto, represeta um bug encontrado. No painel da esquerda, se se clicar no símbolo de + ao lado do inseto, serão abertas várias opções e à direita, os testes realizados. Se dermos um duplo clique em Flight, se abrirá uma tela onde se pode ver a tela de transação Flight, os passos que integram o test realizado, o tempo que cada passo tomou e seu resultado. Página 44

Baixando a barra, verá que aparece o erro de validação do preço do voo, indicando qual foi o valor esperado e qual foi o valor real obtido. Se clicar sobre a linha do erro, abaixo, se abrirá uma tela do navegador com o valor calculado incorretamente. Volte à transação Flight, deixe a fórmula como estava antes (volte a colocar 100 em vez 10) e volte a GXtest para executar novamente o caso de teste. Verifique que agora não aparece nenhum símbolo de erro e que o resultado do cálculo do voo é correto, mostrando novamente o valor 2.5000. Verifique o valor clicando sobre a linha que mostra a validação de tal preço e verifique na tela do navagador que se mostrará abaixio que o valor mostrado seja também 2.5000. 19. Precisa-se de uma parte para Smart Devices Agora, imaginemos que nos pedem que parte do aplicativo possa ser executada em um Smart Devices. Que parte? Trabalhar com atrações. Implemente o que for necessário para testar com o emulador de Android. Se agora quiser que a lista de atrações turísticas saia no emulador como pontos em um mapa, o que deverá ser alterado? Página 45