Você está na página 1de 18

Curso GeneXus 9.

0
Ejercicios Prácticos
Julio de 2006

MONTEVIDEO – URUGUAY Av. 18 de Julio 1645 P.4 +598 2 402-2082


CHICAGO – USA 400 N. Michigan Ave. Suite 1600 +(312) 836-9152
MEXICO CITY – MEXICO Calle Leibnitz N° 20, desp. 801 +52 55 5255-4733

SAO PAULO – BRAZIL Rua Samuel Morse 120 Conj. 141 +55 11 5502-6722
Curso GeneXus – Ejercicios Prácticos

Notas previas

El presente material corresponde a los ejercicios prácticos que el alumno del curso GeneXus deberá ir desarrollando en
forma paralela a las clases teóricas.

Con este práctico el alumno podrá familiarizarse con la herramienta, su ambiente, menús, barra de herramientas, etc.,
así como podrá poner en práctica de una manera guiada y gradual los conceptos más importantes.

Finalizada esta parte práctica del curso, el alumno estará en condiciones de analizar una realidad simple y modelarla
utilizando GeneXus, con el apoyo de un instructor, de forma tal de cerrar un módulo completo de aprendizaje
fundamental para poder empezar a desarrollar sus propias aplicaciones.

Dado que la finalidad de este curso es aprender la lógica de GeneXus, su esencia, independientemente de la plataforma
en que la aplicación vaya a implementarse, podría ud. prototipar en cualquiera de las plataformas soportadas por
GeneXus.

El instructor deberá entregarle al comenzar el práctico los datos de la plataforma elegida para el curso, de manera tal
que ud. configure el modelo de prototipo con esa información.

Encontrará notas a continuación de algunos ejercicios, que invitan a la reflexión sobre lo realizado. Fueron incluidas para
que el alumno no pase por alto conceptos teóricos importantes que están siendo aplicados. También las habrá con
sugerencias de variaciones al ejercicio, para que las pruebe si así lo desea.

2
Curso GeneXus – Ejercicios Prácticos

1. Crear una base de conocimiento

Entrar a GeneXus y crear una base de conocimiento de nombre “Practico” para comenzar el desarrollo de la aplicación.

2. Ejercicios de transacciones

A continuación se solicita que se definan algunas transacciones en la base de conocimiento creada antes. Para cada una de
ellas se muestra una imagen del form Web y una lista de atributos a incluir en su estructura (sin embargo, podrá ser
necesario incluir otros). Se ejercitan diversas características de las transacciones (definición de reglas, fórmulas, etc.).

Sugerencias:

- Utilizar la inserción de reglas, funciones, etc., mediante los ítems Insert/Rules, Insert/Functions, etc.
- Decidir qué valor utilizar en la property “Confirmation” y en caso de que su aplicación sea Win, qué valor utilizar
en la property “Client Side Validation”.
- Numerar automáticamente las claves con la propiedad “Autonumber” de los atributos numéricos clave.
- Utilizar: Tools/List Database.
- Utilizar: Tools/List Attributes.
- Hacer Diagrama de Tablas mediante la opción: Tools/Diagrams/Tables.

Transacción “Country”

Atributos:

CountryId Country Identifier Numeric(6)


CountryName Country Name Character(50)

Luego de haber ingresado el CountryId en la estructura de la transacción, con toda su información relacionada
(Description, Type, Nulls, etc.), y cuando esté pronto para digitar el próximo atributo CountryName, en lugar de
digitar la primera letra, “C”, para escribir Country, digite punto ‘.’. ¿Qué sucedió?
Si hace doble clic o F2 sobre el campo Nulls del atributo CountryName en la estructura, se le abrirá un combo box
con los valores posibles para esa propiedad (“Yes”, “No”, por defecto es “No”). ¿Qué sucede si hace lo mismo para
el atributo CountryId? ¿Por qué no aparece el combo para poder cambiar el valor por defecto?

Form Web:

Reglas:

• No se permiten países sin nombre

3
Curso GeneXus – Ejercicios Prácticos

Transacción “Customer”

Definir los dominios: Name como Character(50) y Price como Numeric(9.2), siguiendo lo que se indica a continuación.

Existen distintos caminos que conducen a la definición de un dominio:


Cuando antes de comenzar a crear las transacciones ya se identifica que se necesitará determinado dominio, puede
crearse mediante Advanced/Domain. Pruebe definir el dominio Name de esta manera centralizada. Luego lo
utilizará en las transacciones, cuando defina atributos que desee estén basados en ese dominio. Observe qué sucede
al digitar CustomerName en la estructura de la transacción “Customer” de más abajo, cuando quiera definir ese
atributo ya habiendo definido el dominio de nombre Name. ¿Por qué sugiere como tipo de datos el del dominio?
Otro camino posible de definición de un dominio es en la propia definición de un atributo en la estructura. Si el
analista no se hubiese percatado de que iba a necesitar el dominio Price y cuando está ingresando el atributo
CustomerTotalPurchases lo hace, puede definir el dominio directamente asociándoselo al tipo de datos del atributo.
Así, en el campo Type del atributo CustomerTotalPurchases, pruebe escribir: “Price=Numeric(9.2)”. Luego de
hacerlo y grabar, vaya a Advanced/Domain para ver todos los dominios definidos en la KB. ¿Está allí Price?

Asígnele a CountryName el dominio Name.

Atributos:

CustomerId Customer Identifier Numeric(6)


CustomerName Customer Name Name
CustomerAddress Customer Address Character(30)
CustomerGender Customer Gender (Sexo de Cliente) Character(1)
CustomerTotalPurchases Customer Total Purchases Price
(Total de compras de Cliente)
CustomerTotalPayments Customer Total Payments (Total de Price
pagos de Cliente)
CustomerBalance Customer Balance (Saldo de Clente) Price
CountryId Country Identifier Numeric(6)
CountryName Country Name Character(50)

Edite el dominio Name y modifique su tipo de datos para que en vez de Character(50) sea Character(30). Observe la
repercusión en los atributos que tienen este dominio asociado (ver atributos CountryName y CustomerName).

Autonumere el atributo clave (CustomerId).

4
Curso GeneXus – Ejercicios Prácticos

Form Web:

Generalidades:
• Definir CustomerGender para que aparezca en el form como un control Radio Button.

Existen dos posibilidades, de las cuales deberá elegir una:


Hacerlo a través del diálogo de definición del atributo (esto es: en la ESTRUCTURA de la transacción, botón derecho
sobre el atributo CustomerGender/Properties/tab “Control Info”). De esa forma cada vez que se inserte un control
atributo correspondiente a CustomerGender en un form de cualquier objeto GeneXus, se insertará por defecto como
Radio Button.
La otra posibilidad sería definirlo a nivel del control en el form de “Customer”, esto es, haciendo botón derecho sobre
el atributo CustomerGender en el FORM/Properties/tab “Control Info”. Pero si se hace aquí, solo vale para este
control en este form y en ningún otro.

Reglas:
• No se permiten clientes sin nombre.
• Avisar en caso de que no se ingrese la dirección.
• No permitir que se ingrese valor en el total de compras (se irá actualizando dede las facturas del cliente).
• El saldo del cliente se calcula como la diferencia entre sus compras y pagos.
• No permitir que se ingrese valor en este atributo (CustomerBalance)

CREAR UN MODELO DE PROTOTIPO

Luego de definidas las dos transacciones anteriores en el modelo de Diseño, querrá probar en ejecución lo hecho, para lo
cuál deberá implementar la aplicación en una plataforma determinada.

Recuerde que un modelo de prototipo o producción corresponderá a una implementación del sistema.

Defina su modelo de prototipo con la información que le brinde el instructor.

5
Curso GeneXus – Ejercicios Prácticos

Deberá configurar la interfaz que utilizará (win o web), el lenguaje (ej: .Net), DBMS (ej: Sql Server), así como el
servidor en el que se encuentra la base de datos que asociará a su modelo, en la que se crearán las tablas, el
nombre de dicha base de datos, usuario y password de la base de datos con los que se conectará a la misma, etc.
Cuando termine de configurar el modelo se realizará el análisis de impacto, cuyo resultado será el IAR (reporte de
análisis de impacto). Observe detenidamente la información que le brinda el reporte. Luego de ejecutado el
programa de Creación de la base de datos, estará pronto para generar los programas correspondientes a los dos
objetos creados. Puede abrirse una ventana inmediatamente después, que le preguntará si desea ejecutar
GeneXusQuery. Dígale que NO.

Especifique y genere sus objetos (aquí generará los fuentes en el lenguaje elegido; por ejemplo, si su prototipo es .Net se
creará por cada objeto GeneXus un archivo de extensión cs)
Compile y ejecute el DeveloperMenu (menú creado automáticamente por GeneXus que contiene una entrada por cada
objeto generado. Desde allí podrá ejecutar sus dos transacciones).
Ingrese algunos países y clientes. Luego:

Pruebe ingresar un país sin nombre.


Pruebe los botones de navegación para recorrer los países ingresados.
Pruebe seleccionar un país de los existentes, utilizando el botón Select. ¿Qué objeto es el que se abre al hacerlo? ¿Lo
programó ud.? Vaya a su KB y búsquelo en la lista de objetos.
Pruebe editar un país existente, digitando su código en el campo CountryId y presionando el botón “Get” a su lado si
su prototipo es Web ó si es Win (y está trabajando sin Client Side Validation). Pruebe vaciar el campo
correspondiente al nombre del país y aplicar los cambios.
Pruebe al ingresar un cliente nuevo, digitar un identificador de país inexistente, o dejarlo vacío. ¿Qué índice utilizó
GeneXus para realizar este chequeo?
Luego presione la imagen de prompt al lado de CountryId si su aplicación es Web (haga F4 sobre el campo CountryId
si su aplicación es Win) y seleccione uno de los países existentes. ¿Qué objeto se abrió al hacer esto? Observe que es
el mismo que cuando presionó Select para elegir un país en la transacción “Country”.
Pruebe dejar vacío el nombre de un cliente, y luego la dirección. Observe que CustomerTotalPurchases está Read
Only, al igual que CustomerBalance. ¿Por qué?
Pruebe eliminar un país para el que tenga por lo menos un cliente asociado. ¿Qué índice utilizó GeneXus para realizar
ese chequeo e impedir la eliminación?
Ingrese 2 clientes con el mismo nombre. A continuación veremos cómo evitar que esto suceda.

Clave candidata
Si en su realidad no pueden existir 2 clientes con el mismo nombre, es decir, si CustomerName no puede tener valores
duplicados, ¿cómo representa esto en el Diseño para que sea chequeado automáticamente?

Defina un índice unique sobre la tabla CUSTOMER, compuesto por el atributo CustomerName, de tipo ascendente.

Deberá ir al modelo de Diseño para hacer esto. ¿Por qué?

Especifique y genere la transacción “Customer” (Build/Specify…)


Compile y ejecute el DeveloperMenu y observe lo que sucede en ejecución si ahora intenta insertar dos clientes con el
mismo nombre.

Efecto de permitir valores nulos en atributos foreign key

Como habrá visto, los programas GeneXus controlan la integridad referencial entre las tablas, de modo que no se le
permitió ingresar un cliente en la transacción “Customer” sin asociarle país (sin ingresar un código de país válido).
Pero algunos clientes pueden no brindarle la información del país del que son originarios, o puede ser información
desconocida para algún cliente en particular. Si desea poder ingresar un cliente sin país asociado, ¿qué deberá modificar
del diseño de la transacción “Customer”?

¿Por qué no puede modificarse el valor de la columna Nulls del atributo CountryId en la estructura de la transacción
“Customer” en el modelo de Prototipo y deberá ir a Diseño para hacerlo?

Después de modificada en Diseño la propiedad Nulls del atributo CountryId, que es foreign key en “Customer”, pase a
Prototipo para probar en ejecución la nueva transacción. Para ello especifique y genere nuevamente la transacción
“Customer” para que se tenga en cuenta el cambio en el programa generado. Compile y ejecute intentando dejar un
cliente sin país y observe que ahora esto será posible.

6
Curso GeneXus – Ejercicios Prácticos

Transacción “Product”

Atributos:

ProductId Product Identifier Numeric(6)


ProductDescription Product Description Character(30)
ProductStock Product Stock Numeric(4)
ProductPrice Product Price Price

Form Web:

Reglas:
• No aceptar el stock del producto si se está modificando un artículo ya existente; solo permitir ingresar el
stock del producto si se está insertando un producto.
• No permitir que el stock quede con valor vacío cuando se ingresa un producto nuevo.

¿Por qué no pudo crear esta transacción en el modelo de Prototipo?


Puede pasar a Prototipo nuevamente después de creada esta transacción en Diseño, para probar en ejecución la
nueva transacción, o puede hacerlo después de que cree la transacción de facturas que sigue. Sugerimos esto
último. En el momento en que pase a Prototipo, no olvide estudiar el IAR (reporte de análisis de impacto) que se le
desplegará en ese pasaje. En él se le informará acerca de las tablas que deberán crearse, índices, etc.

Transacción “Invoice”

Atributos:

InvoiceId (autonumerado) Invoice Identifier Numeric(6)


InvoiceDate Invoice Date Date
CustomerId Customer Id Numeric(6)
CustomerName Customer Name Name
CustomerTotalPurchases Customer Total Purchases Numeric(9.2)
(Total de compras de Cliente)
InvoiceLineId Line identifier Numeric(2)
ProductId Product Identifier Numeric(6)
ProductDescription Product Description Character(30)
ProductStock Product Stock Numeric(4)
ProductPrice Product Price Price
InvoiceLineQuantity Invoice Line Quantity Numeric(3)
(Cantidad llevada de Producto)
InvoiceLineAmount Invoice Line Amount Price
(Importe de Línea)
InvoiceTotal Invoice Total Price

7
Curso GeneXus – Ejercicios Prácticos

(Importe total de Factura)

Form Web:

Observar que esta transacción es de dos niveles. ¿Le puso nombre al nivel 2? Si ud. no lo hace, GeneXus lo hará por ud.
¿Qué nombres le dará GeneXus por defecto a las tablas correspondientes al primer nivel y al segundo de la transacción
“Invoice”?
Vaya al folder de nombre “Tables” que aparece en el árbol de directorios de la izquierda del ambiente de Prototipo y
observe las tablas que GeneXus diseñó de acuerdo al diseño de transacciones que ud. realizó. Busque las tablas que
correpondan al nivel 1 y 2 de la transacción “Invoice” y observe qué atributos aparecen en cada una. Observe que la
clave primaria de la tabla correspondiente al nivel dos está conformada por dos atributos: InvoiceId e InvoiceLineId.
Observe los índices que creará GeneXus sobre esta tabla.

Observe que el form anterior está personalizado: CustomerId y CustomerName se han puesto en la misma fila.
CustomerTotalPurchases no aparece en el form (Deberá borrar este control).

Puede mover controles arrastrando el mouse, y:


En form Web: los controles se alinean colocándolos en tablas. Recuerde que con el ícono de la paleta de

herramientas Formatting indicado aquí: logra que se le muestren en diseño los bordes de las tablas
donde están contenidos los controles del form. Cliquee allí y le aparecerán dichos bordes.
Para eliminar una fila vacía de una tabla, posicionándose en una celda de esa fila, hacer botón
derecho/Table/Delete Rows. Para insertar una tabla, un camino possible es Insert/Table.

En form Win: los controles se alinean utilizando la paleta de herramientas Form.

Obsérvese que ProductStock no aparece en el grid del form presentado antes. Deberá borrarlo. Para ello recuerde que
para trabajar con las columnas de un grid y eliminar atributos o variables de las columnas, reordenar las columnas, etc
cuenta con:
En form Web: botón derecho/Column sobre él. Observe que aquí aparecerán no solo los atributos del 2do. nivel
de la transacción, sino que la primera columna corresponde a una variable &GxRemove, que aparece en el grid como
un check box. ¿Para qué incluye GeneXus esta variable automáticamente? Le quedará más claro cuando ejecute la
aplicación.
En form Win: botón derecho/Properties.

8
Curso GeneXus – Ejercicios Prácticos

Los nombres de las columnas del grid se han acortado (no coinciden con las descripciones que le dimos a los atributos).
¿Cómo logra esto? Recuerde que puede especificar el nombre que desea que aparezca por defecto como título de
columna de un atributo cuando éste aparezca en grids, mediante la propiedad del atributo: Column Title. (haciendo
botón derecho/properties sobre el atributo en la estructura). La otra opción es cambiar el título del atributo en la columna
del grid particular donde se encuentra. ¿Cómo?

El control atributo InvoiceTotal aparece en rojo y a la derecha. Para lograrlo:


Web: observe que todos los atributos del form y sus descripciones, así como el grid, se encuentran dentro de una
tabla de 7x2 (7 filas x 2 columnas), donde el número de filas, 7, corresponde a la cantidad de atributos del primer
nivel (6) más 1 para el grid del 2do. nivel. Posiciónese en la fila donde se encuentra el atributo InvoiceTotal. En la
primera celda de esa fila encontrará el text block con su título “Invoice Total”, y en la segunda está el atributo
InvoiceTotal. Posiciónese en la celda donde se encuentra el atributo. Haga botón derecho/Properties, y modifique
la propiedad Align para lograr una alineación derecha del contenido de la celda. Luego inserte dentro de esa misma
celda una tabla de 1x2 y mueva los controles texo y atributo correspondientes a InvoiceTotal a c/u de las celdas de
la tabla que acaba de crear. Para modificar las propiedades de esos controles (uno está en negrita, el otro en rojo)
seleccione cada control y mediante botón derecho modifique la propiedad que corresponda.

Win: se arrastra con el mouse al lugar donde desea que quede. Puede utilizar la plaleta de herramientas Form para
alinear los controles. Para que salga en el form de color rojo además cambiar al valor Original la propiedad del
modelo de prototipo “Color in Read-Only Fields”. (Esto se hace en: File/Edit Model/botón “Properties”/grupo “User
Interface”/property “Color in Read-Only Fields”)

Reglas:

1. Hacer que la fecha de la factura sea la del día por defecto.


2. No permitir ingresar fecha vacía, ni mayor a la del día.

Ejecute y pruebe las dos transacciones anteriores.

¿Pasó a Prototipo, especificó y generó los programas correspondientes a “Product” e “Invoice”?


¿Compiló?
Pruebe el manejo de datos dentro del grid. Intente insertar, modificar y eliminar líneas del grid de una factura.

Agregue las siguientes reglas a la transacción:

3. Numerar las líneas de la factura en forma automática (a partir de aquí el atributo InvoiceLineId no necesita ser
ingresado por el usuario. Deshabilitarlo.)
4. Actualizar el total de compras del cliente.
5. Actualizar el stock del producto.
6. Controlar que el stock del producto no sea menor que cero.
7. Evitar que se ingresen más de 5 líneas en la factura (relacionado a fórmula 3).

Fórmulas:

1. Calcular el importe de cada línea de la factura (InvoiceLineAmount).


2. Calcular el total de la factura (InvoiceTotal).
3. Contar la cantidad de líneas ingresadas.

¿Tiene que ir a Diseño para agregar reglas en una transacción? ¿No es suficiente definirlas en la transacción en
Prototipo?
¿Por qué debió incluir el atributo ProductStock en la estructura de la transacción pese a que no lo incluyó en el form?
(lo mismo que para CustomerTotalPurchases)
¿Cómo muestra GeneXus la fórmula 3 en la estructura de la transacción: en mayúscula o en minúscula (COUNT ó
Count)? ¿Existe alguna diferencia?
Recuerde volver a especificar y generar el objeto que sufrió las modificaciones para que se cree el programa
correspondiente con las modificaciones (sino quedará el viejo). Aquí solo modificó la transacción “Invoice” por lo que
no necesita hacer “Build All”…sino “Sepecify”.

Ejecute y pruebe la transacción.

9
Curso GeneXus – Ejercicios Prácticos

Regla de asignación versus fórmula

Visualice en el form de “Invoice” el saldo del cliente. Recuerde que:


CustomerBalance=CustomerTotalPurchases - CustomerTotalPayments.

Si solamente inserta el atributo CustomerBalance en el form y olvida declararlo en la estructura le dará un error al
grabar (‘Atributo’: Invalid attribute). Recuerde declarar siempre en la estructura los atributos de la tabla extendida
que vaya a utilizar en el form o en las reglas.

Pruebe ingresar una factura para un cliente determinado y observe que se dispara la regla 4 definida: add( InvoiceTotal,
CustomerTotalPurchases), pero no se actualiza el saldo, CustomerBalance, de acuerdo al cálculo anterior. ¿Por qué?
Modifique el atributo CustomerBalance para que siempre que se consulte, desde cualquier objeto GeneXus, se calcule.

Normalización

Si en la estructura de la transacción “Invoice” se agregan al primer nivel los atributos CountryId y CountryName, ¿qué
ocurrirá con la tabla INVOICE? ¿Se almacenará el atributo CountryId como foreign key a la tabla COUNTRY? ¿O se
normalizará y GeneXus entenderá que ese atributo deberá inferirse, al igual que CustomerName, del cliente, CustomerId?
Pruébelo en GeneXus y corrobore si el comportamiento es el que ud. esperaba. Reflexione sobre lo hecho.

¿Y si quisiera que la factura tuviera un país propio, que el usuario final deba ingresar junto con la factura, es decir, si
quisiéramos que el país no fuera inferido del cliente? Por ahora ud. no cuenta con las herramientas para resolverlo.
Lo hará al final del práctico, cuando estudie subtipos.

Transacción “Customer”

Compare el form que mostramos antes para la transacción “Customer” con el siguiente (encuentre las diferencias):

10
Curso GeneXus – Ejercicios Prácticos

Lo que se hizo aquí fue “disfrazar” el atributo CountryId de CountryName, para permitirle al usuario en ejecución
trabajar con descripciones en lugar de tener que trabajar con códigos. Para el usuario será más fácil recordar el
nombre de un país, que su identificador. El sistema internamente sigue trabajando con el identificador. ¿Cómo se
logra este comportamiento?
Pruébelo en su transacción, editando las propiedades del control atributo CountryId en el form (botón
derecho/Properties) y modificando la propiedad que corresponda de forma de conseguir lo que busca (sugerimos
revisar el material teórico). Deberá quitar el atributo CountryName del form, pues ya no será necesario.

Al hacerlo en el control del form, en lugar de hacerlo de manera centralizada en las propiedades del atributo en la
estructura, solo aplicará a este form particular de esta transacción particular.

Especifique y genere nuevamente el objeto, compile y ejecute, probando el nuevo comportamiento.

Pruebe, sumada a la utilización de descripciones en lugar de códigos, la facilidad de sugerirle al usuario en ejecución
a medida que va digitando el nombre del país, todos los países que empiecen con las letras que el usuario haya
digitado hasta el momento, de manera tal que no deba recordar el nombre completo de memoria, sino solo cómo
empieza, para poder luego seleccionarlo de los sugeridos.

11
Curso GeneXus – Ejercicios Prácticos

3. Ejercicios de reportes y procedimientos

A continuación proponemos realizar una serie de reportes.

Interfaz Web: para poder visualizar directamente desde el browser un reporte, debe ser generado como PDF. Debe
configurar las siguientes propiedades del objeto reporte:
Main = ‘YES’
Call Protocol = HTTP
Report Output = Only to File
Y la siguiente regla:
Output_file(‘nombre-archivo.pdf’ , ‘PDF’)

1. Reporte de clientes en un rango de nombres [si está prototipando en Win: el rango será definido por el usuario; en
caso contrario (prototipo Web) hasta que no estudie web panels deberá dejarlo fijo en el Source (hardcoded). Si ya vio
como implementar un Web panel para pedirle datos al usuario, hágalo]. Los datos que se desean listar para cada
cliente son : Nombre, Dirección y Saldo (Balance).

Al crear un objeto reporte se le abrirá automáticamente el Report Wizard para ayudarlo en la definición del Layout y
Soruce del reporte. Cancele este Wizard, así practica la creación de cero del reporte.
¿Es necesario pasar a Diseño para crear un reporte, o puede crearse directamente en Prototipo?
Al especificar el reporte dedique unos minutos a estudiar el listado de navegación (es muy importante hacerlo en
todos los casos).
Observe el orden que eligió GeneXus para el for each. ¿Está optimizado este reporte?
Observe las diferencias en el listado de navegación que surgen de agregar o quitar la cláusula “order
CustomerName” del for each.
¿Qué tablas está accediendo el for each?
Ahora agregue el nombre del país del cliente a la información que quiere mostrarse, y observe la repercusión en el
listado de navegación.

2. Reporte de la factura al finalizar el ingreso de la misma en la transacción “Invoice”.

Recuerde detenerse a observar el listado de navegación resultante de la especificación de su reporte.


Debió incluir un parámetro para recibir el identificador de la factura que se debe imprimir. ¿Este parámetro lo declaró
como el atributo InvoiceId, o definió una variable? ¿Qué cambios deberá hacer en su reporte si ahora declarara como
parámetro la opción contraria a la que eligió? ¿Qué solución es preferible en este caso?
¿Qué información aparecerá listada si desde la transacción “Invoice” invoca este reporte con la regla call
condicionada a: “On BeforeInsert”?
¿y a “On AfterInsert”?
Estaría bien condicionar el disparo a ¿“On AfterInsert Level InvoiceLineQuantity”?
Y a ¿”On AfterLevel Level InvoiceLineQuantity? ¿Qué diferencia este caso con “On AfterComplete”?

3. Reporte de ventas por cliente, incluyendo sólo los clientes que tienen facturas (Corte de Control).

Cliente : CliXXX

Id. Factura Fecha Importe


1 01/01/06 $150
2 01/02/06 $1000

Total de ventas: $1150

Cliente : CliYYY

Id. Factura Fecha Importe


15 01/01/06 $700
11 01/02/06 $300

Total de ventas: $1000

12
Curso GeneXus – Ejercicios Prácticos

Observe cuidadosamente el listado de navegación. ¿Cómo sabe que implementó un corte de control?
Si además de querer agrupar las facturas por cliente, totalizando el importe, desea que salgan ordenadas las
facturas por número, ¿qué deberá hacer? Pruébelo. En el ejemplo la factura 11 debería salir antes que la 15.
¿Por qué GeneXus informa en el listado de navegación que el orden será el mismo para los dos for eachs, incluso
cuando ud. especificó un orden para el externo y otro orden para el anidado?

4. Reporte de ventas por fecha, agrupadas por cliente. Es decir, para cada fecha en la que hay facturas, se desea ver la
información de las mismas (Identificador e Importe), pero agrupada por cliente. (Doble corte de control).

Fecha: 01/01/06

Cliente: CliXXX
Id Importe
2 $150
3 $10

Cliente : CliYYY
Id. Importe
1 $700
4 $300

Total de ventas: $1160

Fecha: 02/02/06

Cliente: CliYYY
Id Importe
5 $200

Total de ventas: $200

Este tema no aparece en las transparencias del curso, pero sí en las notas que se incluyen al final del tema Corte de
Control. Lea cuidadosamente el ejemplo e implemente el reporte que se le pide.
¿Cuántos for eachs son necesarios para implementar un corte de control doble?
¿Dónde se especifica cada criterio de corte?

5. Realizar la siguiente modificación de diseño en la transacción “Product”: que cada producto en lugar de tener un
solo precio, tenga un histórico de precios según la fecha.

Es decir, la estructura de la transacción “Product” quedaría:

ProductId Product identifier Numeric(6)


ProductDescription Product description Character(30)
ProductStock Product Stock Numeric(4)
(ProductDate* Product Date Date
ProductPrice) Product Price Price

Y su form Web:

13
Curso GeneXus – Ejercicios Prácticos

Como consecuencia del cambio de diseño anterior en la transacción “Product”, ya no es posible inferir el atributo
ProductPrice en el segundo nivel de la transacción “Invoice” (porque ProductPrice ya no pertenece a la tabla extendida de
la tabla INVOICELINE).
Se debe quitar al atributo ProductPrice del segundo nivel de la transacción “Invoice”, definir un nuevo atributo
(InvLineProductPrice) y calcular el valor de ese atributo (hay que encontrar el precio del producto de acuerdo a la fecha de
la factura).

Tiene varias opciones, una de las cuales es invocar a un procedimiento que realice el cálculo devolviendo el resultado.
Podrá definir a InvLineProductPrice como fórmula horizontal, que se calcula mediante el procedimiento anterior.
Implemente el procedimiento que busque el precio del producto de acuerdo a la fecha de la factura y lo devuelva como
resultado en el atributo fórmula anterior.

6. Definir un procedimiento para generar una nueva lista de precios para los productos. El procedimiento debería recibir
por parámetros: fecha de aumento y porcentaje de aumento. Otra vez, cuando estudiemos el objeto Web Panel podrá
realizar este pedido al usuario e invocar a este procedimiento enviándole esos parámetros. Por ahora, coloque esos
valores en el Source de manera fija (hard code) y pruebe de esa manera. Para cada producto deberá generar un
nuevo registro en el histórico de precios, con la fecha ingresada como parámetro y el precio que resulte de aplicar el
porcentaje de aumento, al último precio del producto, anterior a la fecha de aumento.

En el procedimiento suponemos que no existirán registros para la fecha (recibida por parámetro ó hardcoded), y por
tanto siempre se insertará un nuevo registro para cada producto. Modifique ahora su solución de forma tal de que si
sí existiera ya un registro para algún producto con la fecha recibida, el mismo se actualice de forma tal de aplicarle el
porcentaje a su precio.

7. Definir la transacción “Receipt” (recibo) de estructura:

ReceiptId Número de Recibo Numeric(6)


ReceiptDate Fecha de Recibo Date
CustomerId Código de Cliente Numeric(6)
ReceiptTotal Importe total de Recibo Numeric(9.2)

Y definir un procedimiento que realice lo siguiente: para cada cliente, sumarice el importe total de todas sus
facturas, y genere un recibo de pago para el cliente, con la fecha del día, y el importe total a cobrarle.

En la solución que implementó, si un cliente no tuviera facturas, ¿tendría igualmente un recibo por total cero,
generado? Si la respuesta es afirmativa, ¿cómo modifica esto para que solo los clientes con facturas tengan un
recibo generado?

14
Curso GeneXus – Ejercicios Prácticos

Ejercicios de web panels

Generalidades: Crear un folder y agrupar en el mismo a los web panels que se definan.

Para definir web panels, las principales funcionalidades se encuentran en las barras de herramientas que se detallan a
continuación:

Las opciones de esta segunda barra son accesibles mediante las opciones del Menú- Insert.

Definir web panel “Work With Customers”:

Deberá realizar los siguientes pasos:


1. En el form, definir una tabla sin título (Insert/Table) de 2 (Filas) X 3 (Columnas).
2. En la celda superior izquierda, incluir el texto ‘Customer Start Name’ y en la celda inferior izquierda el texto ‘Customer
End Name’.
3. Definir las variables &CustomerStartName y &CustomerEndName haciendo un Copy From del atributo CustomerName.
4. En la celda de posición [1,2] (Notación: [Fila,Columna]) incluir la variable &CustomerStartName; y en la celda [2,3] la
variable &CustomerEndName.
5. Incluir un control de tipo botón en la celda [3,3] y asociarle el evento Enter. Modificar la propiedad ‘Caption’ del botón
para que aparezca el texto ‘Search’ desplegado en el mismo.
6. Definir más abajo en el form otra tabla sin título de 2 X 1.
7. Insertar en la celda [2,1] un grid como se muestra en la figura. Definir las condiciones y eventos necesarios para que
se carguen en el grid solamente aquellos clientes que se encuentren en el rango especificado en las variables
&CustomerStartName y &CustomerEndName. Contemplar que si se dejan vacías las variables, se carguen en el grid
todos los clientes.
8. Para que el grid se presente como se muestra en la figura, modifique su propiedad BackColorStyle y póngale tipo
Report.
9. Agregar tres botones al web panel (en la celda [1,1]) , e invocar en sus eventos a la transacción “Customer” para que
sea posible realizar altas, bajas y modificaciones de clientes.

15
Curso GeneXus – Ejercicios Prácticos

10. Definir los eventos de usuarios necesarios para poder realizar con los registros todas las operaciones descriptas en el
punto anterior.
11. Programar los eventos necesarios para realizar la paginación de los registros.

Observar que en el grid de este web panel no se está mostrando el atributo CustomerId. Estudie si hay que realizar
algo con dicho atributo para que las funcionalidades solicitadas se ejecuten adecuadamente.

12. Agregar un botón más en el form e invocar en su evento al web panel “View Customer Invoices” pasándole por
parámetro el cliente (CustomerId) que se encuentre seleccionado en la grilla.
13. Definir el web panel “View Customer Invoices”:

que recibe por parámetro un identificador de cliente (del cual se desean consultar sus facturas).

Se desea que el web panel “View Customer Invoices” despliegue la lista de facturas ordenada por fecha, del cliente
recibido como parámetro. Los datos que se desean desplegar en la parte fija del web panel son Identificador y Nombre
del cliente, y en la grilla: Nro. de Factura, Fecha y Total de Factura.

Además:

• Incluir en este web panel un bitmap con el logo de la empresa (una imagen cualquiera).
• Agregar un botón en este web panel, que al presionarlo llame a la transacción “Invoice” en modo display para
visualizar todos los datos de la factura seleccionada.

14. Definir el siguiente web panel “sin tabla base”: se solicita un web panel que muestre para cada cliente, su total
facturado, pero sólo de los clientes que tengan facturas. En tiempo de ejecución el resultado de la consulta deberá
lucir así:

15. Resolver la misma consulta que se solicita en el punto anterior con web panel “con tabla base”.
16. Definir un web panel con 3 grids: en el primer grid se deben mostrar todos los clientes; y cada vez que el usuario
seleccione un cliente en el mismo, se deberán cargar sus facturas en el segundo grid. A su vez cada vez que el usuario
seleccione una factura del segundo grid, se deberán cargar sus líneas en el tercer grid.

16
Curso GeneXus – Ejercicios Prácticos

4. Modificar el Prompt de Productos (generado por defecto)

El Prompt de Productos es un web panel (generado automáticamente por GeneXus, de nombre GX00NN) que puede ser
llamado desde la transacción de facturas y permitirá seleccionar un producto.

Lo que se pide es tener la posibilidad de dar altas, bajas y modificaciones de productos (llamando a la transacción
“Productos”) desde este prompt.

17
Curso GeneXus – Ejercicios Prácticos

5. Subtipos

Si ahora queremos representar que una factura pertenece a un país, independientemente del país del cliente de la
misma, ¿qué modificaciones debe realizar? Impleméntelas.

Observar que la factura pertencerá a un país, por ejemplo Uruguay, y el cliente de la factura podrá pertenecer a otro
país distinto, por ejemplo United States.

6. Business Components

Para probar las ventajas que brinda la posibilidad de encapsular toda la lógica de una transacción para poder actualizar y
consultar la información de sus tablas sin requerir de su interfaz, pero aplicando toda esa lógica, cree un procedimiento o
reporte a partir del cual ingresará varias facturas al sistema, utilizando business components en lugar del comando new del
procedimiento.

¿Qué ocurre cuando edita las propiedades de la transacción “Invoice” y configura la propiedad “Business Component”
en True y graba? Aparecerán dos nuevos tipos de datos Business Components. Observe los nombres dados a los
mismos.
¿Qué sucede al especificar la transacción “Invoice”? ¿Por qué aparecen dos listados de navegación?
¿Cómo utiliza ahora estos business components creados dentro del reporte o procedimiento para dar de alta algunas
facturas? Observe que necesita crear una variable basada en el business component correspondiente al cabezal de
factura y otra para las líneas.

Dé de alta en el reporte o procedimiento una factura correspondiente a un cliente que exista, en la fecha de hoy, y luego
dos líneas, con productos existentes, que tengan stock suficiente. Es decir, asegúrese de ingresar una factura cuyo ingreso
sería exitoso si se hiciera a través de la transacción.

Ejecute el reporte o procedimiento, abra la transacción “Invoice” y posiciónese en el último registro. Deberá corresponder
al que ingresó en forma batch.

Ahora modifique el reporte o procedimiento anterior, ingresando un cliente inexistente, en una fecha mayor a la del día de
hoy, un producto inexistente para una línea, y para la otra un producto que exista, pero que no tenga stock suficiente para
cubrir la cantidad llevada.
En el mismo reporte y procedimiento, programe el manejo de errores, es decir, consulte la lista de mensajes del business
component, mostrándolos en pantalla mediante el comando msg.

Ejecute nuevamente el objeto y luego abra nuevamente la transacción “Invoice”

¿Se generó esta nueva factura? ¿Por qué no?


Deberá concluir que se dispararon todas las reglas especificadas en la transacción asociada al business component.
De haber realizado las inserciones anteriores en un procedimiento, a través del comando new, ¿qué hubiese pasado?

7.

18

Você também pode gostar