Control de acceso a programas. Adaptación a la LOPD.

Saludos a todos.

Hace poco me tuve que enfrentar al desafío de adaptar una aplicación mía hecha con Velneo a la normativa de la LOPD ( Ley Orgánica de Protección de Datos, en España ). Esta ley, exige entre otras muchas cosas un control de acceso a las aplicaciones, los válidos y los no válidos, guardando en un fichero Log tanto los intentos de acceso exitosos como los fallidos, con una serie de datos como la IP desde donde se realizó el acceso, el nombre de usuario y contraseña, la fecha y la hora.

También es obligado el cambio de contraseñas de acceso cada X tiempo, poder hacer listados de accesos, llevar un control de quién accede a la información catalogada como de nivel máximo, cambiante según el objetivo de cada empresa…..

El vServer nos ofrece la aplicación del Historial del Servidor, pero no se adapta por completo  a las exigencias de la Ley. Por ello, tras varias reuniones con el asesor, me dí cuenta de que el control de acceso lo tenía que hacer yo mismo desde el mismo mapa de la aplicación.

Después de meditarlo un tiempo, me puse manos a la obra para resolver todos los requerimientos y me dispongo a compartir mi experiencia con vosotros.

El esquema de tablas que planteo es el siguiente:

Esquema de tablas para control de accesos a aplicación

  1. Tabla USUARIOS: maestra. En ella se guarda el nombre del usuario, su contraseña y el nivel de acceso a la aplicación
  2. Tabla PERMISOS.: maestra. En ella se guarda a qué tiene permiso el usuario. Partí del ejemplo de acceso a menús que pueden tener los distintos usuarios de la aplicación.
  3. Tabla FLAGS: histórica de las dos anteriores. Siguiendo la forma de llamar a los permisos en Velneo, le puse el mismo nombre que la función  fUserFlag. Tiene además un campo booleano para indicar si el usuario tiene permiso o no.
  4. Tabla HCONT: histórica de USUARIOS. Permite llevar un histórico de los cambios de contraseña. Se guarda en ella la fecha de entrada en vigor de la contraseña. Se pueden ampliar el número de campos para indicar la fecha de caducidad, avisos…..
  5. Tabla BOARDS: maestra. En ella se registran las tablas de la aplicación. Hay que introducir los datos a mano, lo siento. Es una lástima que el API de Velneo no sea del todo satisfactorio como para evitar estas cosas y hacerlas de una manera más elegante.
  6. Tabla BOARD USERS: histórica de USUARIOS  y de BOARDS.  Con campos booleanos para poder establecer unas operaciones mínimas como lectura, escritura, modificación y borrado. En este ejemplo no he puesto nada de esta tabla, pues excedería el objetivo de la entrada.
  7. Tabla ACCESOS: maestra. Usada para llevar un registro de los intentos de acceso a la aplicación y si estos han sido correctos o fallidos.
  8. Tabla LOG: histórica. El log propiamente dicho y que servirá de cajón de sastre donde registrar todo lo que queramos , desde un alta hasta una modificación pasando por la ejecución de un proceso.
  9. Tabla MEM: maestra en memoria. Me sirve de base para pedir usuario y contraseña con un formulario.

Tabla histórica del LOG

Para llevar a cabo el control de acceso a la aplicación, en el menú AUTOEXEC he puesto el proceso siguiente como proceso On-init, con el que se controla el usuario, la contraseña, se hacen las comprobaciones, se registra el acceso o intento de acceso y se da el privilegio establecido al usuario.

Proceso control de usuario 2

Con ello guardamos en variables globales en memoria los datos de código de usuario $USER-CODE$ e  ip de acceso $USER IP$ que nos dan toda la información necesaria para dar de alta registros tanto en la tabla ACCESOS  como en la tabla LOG, usando la función siguiente, desde donde se estime oportuno.

A modo de ejemplo, he llamado a esta función desde dos procesos anteriores al botón Aceptar de dos formularios, el de alta de Usuarios y desde el alta de Permisos, pero se puede usar desde un trigger o proceso de tabla o desde cualquier otro proceso ( pérdida de foco, anterior o posterior a botón con acción aceptar o eliminar o….)

En el menú PRINCIPAL  he puesto dos opciones que no disparan ninguna acción, aunque podrían, pero que tienen condición de visibilidad utilizando una función a la que pasándole los parámetros de _usuario y _menu , busca en la tabla FLAGS si el usuario tiene o no autorización a ver ese menú u opción de menú.

¿Está el usuario autorizado a ver esta opción?

Con ella controlamos  la condición de visibilidad de una opción del menú ya que nos retorna el campo AUTORIZADO (booleano) para ese usuario y esa opción.

No he puesto en el ejemplo que os podéis descargar, las opciones y objetos que se utilizan para el control de acceso a tablas con la tabla BOARD-USERS. Si un hombre tiene hambre, no le des sólo un pez, enséñale a pescar.

Un saludo y espero que os guste.

P.D: el usuario por defecto que he puesto tiene los datos

  • Nombre de usuario: superusuario
  • Contraseña: hola

Búsqueda y arrays, una forma de hacer multibúsquedas (y II)

Intentaré explicar con otro ejemplo una nueva forma de hacer multibúsquedas en una tabla de datos usando de nuevo los arrays de Velneo.

El planteamiento es sencillo pero suficiente para desarrollar dos formas de hacer una multibúsqueda sobre una misma tabla: una con una rejilla en la que escogemos los datos de quién queremos mostrar de dentro de una lista de ellos y otra en la que introducimos nosotros los datos como si fuese un histórico.

Tenemos dos tablas, una de CLIENTES  y otra de VISITAS,  ésta última histórica de la primera, en la que iremos guardando las visitas que le hacemos a cada cliente en diferentes fechas. No he querido crear más campos para que el ejercicio fuera lo más sencillo y claro posible.

Esquema inicial de tablas

Esquema inicial de tablas

Primer planteamiento: el objetivo es que la aplicación busque todas las visitas que se han hecho a los clientes que yo elija en una rejilla en la que me muestra todos los clientes. Es lo que he llamado en el mapa visitas múltiple  selección y los objetos usados se guardan en la carpeta del mismo nombre.

He creado una tabla DUMMY  en memoria que se va a cargar con todos los clientes cada vez que se necesite a través de un tubo de lista.

esquema dummy

Esquema de tablas con CLIENTES, VISITAS y DUMMY

Con un formulario especial de la tabla VISITAS donde se muestra una rejilla con todos los DUMMY,  editable en su campo %ESCOGER%,  que en principio vale 0, pero que podemos cambiarlo en esa rejilla a 1 para que nos  busque las VISITAS  a ese CLIENTEDUMMY. Tras tener escogidos los CLIENTES  que queremos el proceso utiliza una cesta de VISITAS  y la potencia de los arrays, para ir cargando en la cesta las visitas de cada uno de los CLIENTES seleccionados y mostrarlos al final en una rejilla de la tabla VISITAS. Como se puede observar, la tabla DUMMY  no tiene ningún tipo de conexión con las otras dos tablas.

proceso multi

Proceso con DUMMY y "multiselección".

En el proceso se crea una cesta local de visitas donde se irán añadiendo las visitas de los CLIENTES  elegidos.

Se vacía la DUMMY   y  se rellena posteriormente mediante un tubo de lista con todos los clientes. Se crea el array.

A continuación se muestra un registro de VISITAS en el que hay una rejilla con los datos de la DUMMY. El primer campo %ESCOGIDO% es editable y se puede cambiar su valor de o a 1.

Se carga la lista DUMMY  por el índice “escogido” ( formado por el código y con campo condición para indexar %ESCOGIDO% igual a 1 ) y se van añadiendo al array los códigos de los clientes guardados en el campo %CODIGO%  de la tabla DUMMY.

Por último se caga el array, y se va leyendo cada item, que irá modificando la variable global en memoria $COD-CLIENTE$ para así lanzar la búsqueda VISITAS-COD-CLIENTE  y añadir los resultados obtenidos a la cesta. Por último se muestra la cesta.

Este planteamiento se lanza en la opción de menú búsqueda múltiple con rejilla editable

Segundo planteamiento. el objetivo es que la aplicación busque todas las visitas que se han hecho a los clientes que yo haya introducido en una rejilla. Es lo que he llamado en el mapa visitas múltiple  dando altas y los objetos usados se guardan en la carpeta del mismo nombre.

He creado una tabla DUMMYDOS  en memoria  a la que se van a añadir los clientes que se quiera mediante un formulario de alta

esquema con dummydos

Esquema con CLIENTES,VISITAS y DUMMYDOS

Esta vez DUMMYDOS si que actúa como histórica de CLIENTES, pues necesito rellenar esta tabla con un localizador y para ello , necesito que CLIENTES sea maestra de DUMMYSDOS.

El proceso llamado varía un poco, pero también creo que es sencillo y fácil de comprender.

proceso dummydos

Proceso que alimenta la cesta de las visitas

En este caso, cuando se recorre la lista de DUMMYDOS,  el dato que se debe añadir al item del array es el puntero al CLIENTE, que guarda el campo %CODIGO% de la ficha del maestro CLIENTES.

El segundo  planteamiento se lanza en la opción de menú búsqueda múltiple con rejilla “alimentada”

Seguro que es mejorable, pero es sólo un ejercicio para ver cuánto partido le podemos sacar a Velneo.

Link de descarga del mapa completo y en el foro de Velneo.

EDICION (8-sep-2010)

Tal y como me comenta por e-mail mi compañero y sin embargo amigo 🙂 Adelo Herrero el primer planteamiento se puede hacer sin la tabla DUMMY  usando la misma tabla de CLIENTES para simular la multiselección con el campo %ESCOGIDO%.

Tienes toda la razón Adelo. Se agradece el comentario y subo al link de descarga la versión actualizada con tu sugerencia.

Un saludo.

Con Velneo se pueden hacer muchas cosas!!!

Hace poco, revisando la Wikipedia, me encontré con este artículo. Me pareció interesante desde el principio  y hoy mismo lo volví a revisar y me propuse dejar a un lado los programas habituales de gestión y dedicarle un tiempo a intentar simular dicho juego.

En principio , la idea se basa en una única tabla, VMAESTROS (aprovechando el almacén de objetos, :-)) que para que los cálculos fueran más ágiles, la hice en memoria.

Incluye cuatro campos además del código:

  • FILA , numérico de longitud 1, para guardar la fila en la que está la ficha
  • COLUMNA, numérico de longitud 1, para guardar la columna
  • VIDA, booleano, para indicar si la célula está viva ( valor 1 ) o muerta (valor 0)
  • SIGUIENTE, también booleano, que me dará el estado de la célula en el siguiente “turno”

De la tabla, sólo conservo el índice código y creé otro formado por la terna FILA-COLUMNA que me servirá para posteriores cálculos además de para mostrar las fichas con el objeto visual casillero, organizado por filas y columnas como si fuera una matriz.

Las premisas del juego so:

  • Una célula muerta con exactamente 3 células vecinas vivas “nace” (al turno siguiente estará viva).
  • Una célula viva con 2 ó 3 células vecinas vivas sigue viva, en otro caso muere o permanece muerta (por “soledad” o “superpoblación”).

El estado siguiente  de una célula  en la posición fila F columna C de su estado inicial y de los estados de las 8 células que le rodean

Trama de las celdas

Luego, el próximo estado de CF ha de depender de otros 8 valores y será calculado por la premisa primera del juego o de la segunda, dependiendo del estado de VIDA  de CF inicial. Y todo ha de calcularse para cada una de  las células.

Para eso utilicé el campo%SIGUIENTE%  en el que podré calcular el valor de CF en la siguiente “jugada”.

proceso recálculoEn el proceso se recorre la lista en modo lectura/escritura, para modificar el campo SIGUIENTE  llamando a la función TOYVIVA  a la que le pasamos los parámetros FILA, COLUMNA y VIDA.

función vida

Calcula el estado siguiente de la celda CF

Si el “no está viva” (parámetro _estado=0), entonces se ataca la segunda premisa y se ve el estado de las otras 8 células que le rodean y se cuentan cuántas de ellas viven. Si viven 3, se retorna como valor de función 1, es decir, en la siguiente jugada la célula estará viva.

Si “vive” (parámetro _estado=1) vamos a la primera premisa pero esta vez inicializamos el contador no a 0 como antes sino a -1 dado que la célula CF ya está viva pero no la podemos contar. Si encontramos que hay 2 ó 3 vivas seguirá viva y si no, morirá en la siguiente jugada.

Una vez la función me devuelve todos los valores, vuelvo a recorrer en el proceso la lista para pasarle al campo VIDA  el valor guardado en SIGUIENTE y volver a poner este último a cero.

Para que fuera algo más vistoso en cuanto a funcionamiento, creé dos menús

  • MENU INICIAL  en el que aparece el casillero para que podamos dar vida a las células que queramos con un click en cada casilla o ponerlas todas a cero. Todas las fichas se crean al iniciarse el programa en el proceso llamado desde el menú AUTOEXEC  con el proceso VMAESTROS (que genera una “matriz! de 40X40) pero que podeis cambiar por el llamado GENERA  que pide el número de filas y columnas a generar
  • MENU VIDA en el que se han sincronizado dos casilleros iguales, pegados uno encima del otro con una variable global booleana VISIBLE que hace los efectos del refresco tras los recálculos. A su vez, para que no se tenga que dar a una opción de menú cada vez que se quiera ver la evolución dinámica del juego, en este menú he puesto una opción texto estático en vertical llamada Recalcular, con la opción Timer, cada cuantos en 1, para que se repita cada vez que el timer del menú ( puesto cada 2000 milisegundos)

Espero que os guste  o que al menos os entretenga.

Para los foreros de Velneo , el enlace de descarga en el foro y para los que no , este enlace de descarga externa.

Un saludo.

Búsqueda y arrays, una forma de hacer multibúsquedas (I)

Hace poco, un amigo me planteó el siguiente problema  que se le daba en una aplicación.

En una empresa, hay una serie de departamentos. Dentro de cada departamento, hay niveles de acceso a la información de una tabla (NOTICIAS). Cada persona de la empresa tiene un determinado NIVEL  dentro de cada DEPARTAMENTO y una persona solo puede acceder a las informaciones de cada uno de sus departamentos y dentro de ellas a las que su nivel se lo permita. Por ejemplo, si hay 10 niveles y tengo asignado en el departamento de contabilidad el nivel 4, podré acceder a toda la información de contabilidad con nivel 4, 5, 6,7,8,9 ó 10.

El esquema de tablas que hice fue el siguiente:

Esquema

Esquema de tablas

La tabla CLASIFICACION  tiene como objetivo mantener un histórico de los DEPARTAMENTOS  y NIVELES que tiene en cada uno de ellos cada PERSONA de la empresa. Tiene solamente tres campos punteros a maestro PERSONAS, DEPARTAMENTOS y NIVELES  y un índice de clave única formado por los tres campos punteros.

La tabla NOTICIAS  ( puede también llamarse APUNTES o NOTIFICACIONES, como cada cual quiera ) tiene un campo CODIGO, NOMBRE y un puntero a DEPARTAMENTO y otro a NIVELES que le renombré como Nivel Mínimo. A su vez creé un índice formado por la terna DEPARTAMENTO-NIVEL .

Para que desde una ficha de modificación de persona, se muestren las NOTICIAS  que le corresponde, monté los siguientes objetos visuales:

  • variable global en memoria  DEPARTAMENTO
  • variable global en memoria NIVEL
  • variable global en memoria TOTAL NIVELES

Las tres numéricas

  • Una búsqueda en la tabla NOTICIAS: NOTICIAS-PERSONA, en la que se busca por dos índices, primero por el de departamento, parte izquierda, valor $DEPARTAMENTO$  al que se le cruza la búsqueda por el índice NIVEL, entre límites, limite inicial $NIVEL$ , límite final $TOTAL NIVELES$
Búsqueda

Búsqueda de noticias-personas

  • Un proceso con origen ficha de PERSONAS que alimenta la rejilla que se mostrará en el formulario de modificación de la persona,con  las noticias a las que tiene acceso.

Proceso

En este proceso son fundamentales tres cosas: la cesta y los dos arrays.

Un array es un vector, con muchas dimensiones, es una forma de guardar datos de forma momentanea en un proceso y acceder a ellos dentro del mismo proceso.

El primer array (array departamento), guardará en cada item el DEPARTAMENTO que se guarda de la persona en la tabla CLASIFICACION y en el segundo (array nivel ) , el NIVEL. Con ello conseguimos tener por cada persona la terna DEPARTAMENTO-NIVEL, cada una en un array.

Sólo nos queda hacer un bucle for que se repita un número de veces igual al número de items que tienen los arrays para ir llamando a la búsqueda NOTICIAS-PERSONAS sucesivamente e ir añadiendo los resultados de cada una de ellas a una cesta local, que al final procesaremos y será la que se muestra en el formulario.

Podeis descargarlo aquí http://forum.velneo.com/es/viewtopic.php?p=80270#80270

Programar es prever

He estado un tiempo sin escribir nada en el blog, y los próximos cambios que se van a dar en la legislación española sobre la aplicación del impuesto del IVA en las facturas me ha animado a hacerlo.

Hasta ahora, la forma habitual de enfocar el recargo del IVA en las facturas, al menos en las aplicaciones que yo desarrollaba y en alguna otra de otros programadores que conozco se basaba en guardar los valores de los porcentajes de los impuestos en variables globales de disco.

El próximo cambio de valores me ha hecho pensar que programar es prever, y quién nos dice que dichos valores no vayan a sufrir variaciones a lo largo del tiempo de aquí a unos meses o años.

Por ello me he planteado pasar todo ello a una estrucutura de tablas lo más flexible posible y que no tenga que implicar la actuación del programador a la hora de hacer estos cambios.

Esquema general de tablas

Esquema general de tablas

Basándonos en una aplicación sencilla de facturas de ventas, el esquema que he ideado es el mostrado en la imagen.

Partimos de una tabla principal de IMPUESTOS  en los que podremos dar de alta tanto IVA como IGIC, IRPF, Recargo de equivalencia….

En la tabla TIPOS-IVA se añadirán los distintos tipos de cada impuesto. Por ejemplo, en el caso del IVA irán los registros: General, Reducido, Superreducido y Exento, por ejemplo.

Y en la tabla valores del IVA , tanto los porcentajes de cada uno de estos TIPOS como su fecha de entrada en vigor.

He añadido además una tabla de COMPATIBLES para tener una relación de qué impuestos son compatibles entre sí y por tanto aplicables en una única factura. Por poner un ejemplo de incompatiblidad, el impuesto IGIC aplicable en la comunidad autónoma de Canarias , NO es compatible con el IVA, pues de alguna forma el primero sustituye al segundo.

Todos los valores anteriores, se dán de alta automáticamente al iniciar la aplicación mediante llamadas a diferentes procesos sin origen en el proceso de arranque GENERAL.

Proceso GENERAL

Proceso GENERAL

Desde este proceso GENERAL  se hacen llamadas a diferentes procesos sin origen que van dando de alta los registros necesarios en las diferentes tablas

Los procesos interesantes son

IVAS-ALTAS

IGIC-ALTAS

IRPF-ALTAS

RECARGO-ALTAS

En la imagen no aparece, pero también se incluye un proceso para dar de alta los registros de la tabla COMPATIBLES.

Podremos escoger qué impuestos vamos a usar de forma general en el formulario de CONFIGURACIÓN  en la pestaña “fiscales” y sus valores habituales , así como personalizar para cada cliente qué impuestos le vamos a aplicar de forma general en las facturas que les emitamos y sus valores, todo ello con subindexaciones para que sólo podamos escoger los TIPOS  del IMPUESTO  elegido.

Así mismo, en los artículos  escogeremos también el IMPUESTO  y su TIPO, calculando el porcentaje aplicado según los dos campos anteriores.

En la tabla de MOVIMIENTOS (lineas de la factura ) en el campo PORCENT-IVA-FACT  he usado como valor inicial la función IVA-PORCENT  a la que le paso los parámetros : fecha de la factura, tipo de impuesto, e impuesto. Esta función, dependiendo de esos tres parámetros, me calcula el valor de ese impuesto-tipo que graba a la linea en esa fecha de factura. La función es manifiestamente mejorable pero me pareció una solución válida para conseguir el fin que se necesitaba, la devolución del tanto por ciento en vigor.

En la tabla FACTURAS uso 7 campos BASE IMP , dado que el IGIC tiene hasta siete registros en la tabla TIPOS-IVA, y desde MOVIMIENTOS hay tambien 7 actualizaciones distintas a los respectivos cambios, todas ellas condicionadas a los distintos binomios IMPUESTO  TIPOS-IVA  que estemos usando.

Como en una factura pueden coexistir dos impuestos que la graban ( por ejemplo IVA y Recargo de Equivalencia ) y uno que la resta  ( IRPF ) he creado los respectivos campos para calcular los valores de dichos impuestos con respecto a las bases imponibles correspondientes, así como la retención del IRPF sobre el total de la suma de las bases, todo ello mediante las funciones correspondientes que dependen de la fecha de la factura, del tipo y del impuesto.

Por último indicar que todo aquel que quiera el mapa del programa, puede escribirme un correo a agustismv@gmail.com y se lo proporcionaré con mucho gusto para que lo useis como queráis.

P. D: pensando en la v7, bastaría con conectar la tabla  VALORES-IVA  con PAISES  y así la tendríamos para distintos paises.

¿Tubos?…¿y eso qué es? (y iii)

Veamos con un ejemplo real la diferencia de actuación de los tubos de lista y de ficha.

Supongamos una aplicación en la que hacemos albaranes y facturas con una estructura de tablas como la siguiente.

Esquema de tablasHe puesto las tablas de cabeceras de albaranes y de facturas como submaestra de años para aprovechar su código como contador y así que comience a contar en 1 en cada año ( ver articulo )

Así mismo las lineas son a su vez submaestras de las cabeceras correspondientes.

Los campos que tenemos en las tablas cabeceras son practicamente los mismo en una y en otra tabla , al igual que ocurre con los campos de las tablas lineas.

Hagamos ahora los objetos visuales que nos permitirán facturar un albarán.

El proceso general para hacerlo sérá: tenemos una ficha de Cabecera de Albarán de la que

cuelgan sus históricos Lineas de Albarán. Tomaremos los datos de la CAlbarán y los pasaremos a un ficha de CFacturas. Una vez hecho esto, he de recorrer las lineas de LAlbaranes para hacer lo mismo, es decir, llevarlas a LFacturas pero indicándoles a dichas lineas a qué CFactura pertenecen. Para ello usaremos dos métodos. El primero mediante dos tubos de ficha y el segundo con un tubo de ficha y otro de lista.

Método 1: dos tubos de ficha

Crearemos primero el tubo de ficha para pasar datos desde una Cabecera de Albarán a una Cabecera de factura

Tubo de cabecera

Vemos que los capilares que usamos son pocos, no  utilizamos todos los campos, sólamente los que son necesarios para definir la factura al final del tubo, el cliente, el año y el almacén, en caso de ser multialmacén. El resto de los campos de CFactura, se “rellenarán” o bien por contenidos iniciales de los mismos o bien mediante actualizaciones desde las lineas

Después creamos el tubo de ficha para las lineas en el que usaré dos capilares, el puntero al Artículo y la cantidad de unidades vendidas.

El proceso para facturar un único albarán será el siguiente.

Proceso en el que ser realiza la facturación de un albarán.

Con lo que obtenemos la factura con sus lineas correspondientes.

Método dos: un tubo de ficha para las cabeceras y un tubo de lista para las lineas

Creamos el tubo de lista desde LAlbaranes a LFacturas, con los mismos capilares que los usados en el tubo de ficha. Los cambios irán en el proceso de facturación que se lanza desde la ficha de CAlbarán

Facturación

Observar que en el post del primer tubo, ya no uso los Set para guardar valores en varialbles locales sino la instrucción de proceso

Guardar ficha, lo que nos permitirá usar un Tubo de lista con inducción. Esta inducción nos permite indicar a todas y cada una de las lineas de factura que se van creando a la salida del tubo de lista a qué ficha de maestro( CFactura) pertenecen.

La inducción hace que cada línea de la factura apunte a la misma cabecera, es decir, introduce el código del registro de la cabecera de la factura en el campo enlazado de los registros de Líneas de Factura.

Cualquiera de los dos métodos es válido. El primero, con tubo de ficha en las lineas, nos permite modificar los registros de salida del tubo, en cambio el tubo de lista no lo permite.

En el caso de tener que facturar varios albaranes en una única factura, podríamos hacer un proceso con origen lista de CAlbaranes para poder lanzarlo como una opción desde una toolbar en una  búsqueda de albaranes presentada en una rejilla multiselección, para ejecutarlo contra los seleccionados. Dividiremos así mismo el proceso en dos. En el primero, ordenamos la lista por Cliente para luego multipartirlo por ese mismo campo. Con ello logramos una “minilista” con cada todos los albaranes de un cliente, y por cada una de esas minilistas, ejecutamos el proceso que los factura.

Proceso llamador

Proceso llamado en el que se realiza la facturación de la minilista de los albaranes de un único cliente. Este proceso se repetirá por cada una de las multiparticiones que se obtengan en el proceso llamador.

Análisis : segunda fase

Una vez que hemos visto cómo usando las frases podemos establecer qué tablas actúan como maestras y cuáles como históricas, vamos a plasmarlo en del vDeveloper. Para ello usaremos el esquema de tablas        barraherramientas.jpg  al que accederemos con el icono de la derecha del todo de la imagen.

El esquema de tablas, aparecido en la versión 2.1 , es un importante asistente a la hora de establecer enlaces entre las tablas de nuestras aplicaciones.

 

Podemos tener en nuestra aplicación tantos esquemas de tablas como necesitemos, pintando en ellos las tablas que  necesitemos. Por ejemplo, podemos tener un esquema para reflejar las relaciones de las tablas de Ventes, otra para las Compras, otra para la Facturación… En el esquema podemos apreciar un area grande a la derecha, en donde se irán pintando las tablas y en la izquierda y de arriba abajo, tres partes, la superior en la que nos vienen listados todos los esquemas que tenemos ( para cambiar de nombre a un esquema sólo hay que posicionarse sobre él y pulsar la tecla F2 ), las tablas del esquema que nos lista las tablas que tenemos en ese esquema en concreto, y las tablas no usadas que son las que no hemos incluido en el esquema en que estamos. Para “sacar” al esquema una tabla que no está, basta ponerse sobre ella en Tablas no usadas y hacer doble click con el botón izquierdo del ratón. Para eliminarla del esquema, que no de la aplicación basta posicionarse sobre ella y pulsar Supr.( eliminar una tabla de un esquema no hace que esta se borre de la aplicación )

Podemos desde aquí crear las tablas, o bien acudiendo al almacén de objetos o a la barra que aparece en la parte  izquierda del editor de esquemas. En ella podemos encontrar, de arriba abajo      

  • Botón para ocultar la parte izquierda                                                                    
  • Botón para nueva tabla Maestra
  • Botón para nueva tabla Submaestra
  • Botón para nueva tabla Maestra de Clave Arbolada          
  • Botón para nueva tabla Histórica.

Usaremos el de la tabla maestra para crear una tabla de Cordilleras y otra de Montañas. Tal y como habíamos analizado en el anterior artículo, Cordilleras es maestra de Montañas. Recomiendo que a la hora de utilizar los esquemas, coloqueis las maestras en la parte de arriba del esquema, y sus histórcas por debajo, esto os dará una ventaja a posteriori pues con un simple vistazo del esquema sabreis qué tablas actúan como maestras y cuáles como históricas.

Enalzando Una vez colocadas en el esquema, nos queda establecer la relación entre ambas. Para ello usaremos el enlazador.Vamos a establecer la relación Cordilleras es maestra de Montañas, de singular Cordilleras a plural Montañas. Si posiciono el ratón sobre el cuadrante gris superior izquierda de la tabla Cordilleras, aparecerá el icono de una mano además del tooltip que se ve en la imagen. Una vez que aparezca la mano pulsamos botón izq del ratón y aparece una flecha roja. Esta flecha roja nos indica que vamos a establecer una relación de Maestro-Histórico con otra tabla. Arrastraremos sin soltar( con la flecha roja visible ) hasta la tabla Montañas y una vez sobre ella dejaremos de pulsar el botón.

Enlazadas

EnlazadasCon ello ya habremos logrado enlazar las dos tablas. El puntero azul, indica que la relación entre Montañas y Cordilleras es de uno a uno ( Una Montaña está en una y sólo en una Cordillera ) mientras que el puntero rojo indica una relación de uno a muchos ( una Cordillera puede tener muchas Montañas )

Esta forma de “pintar” las relaciones entre tablas que Velneo nos proporciona, resulta una herramienta muy potente a la hora del análisis e implementación de nuestras bases de datos. Es básico y fundamental aprender a analizar bien y sacarle así todo el rendimiento al vDeveloper.

Maestras e histórica de enlace Siguiendo el mismo procedimiento de creación de enlaces, podemos enlazar también las tablas del ejemplo de los Artículos y los Almacenes con la histórica de ambas ( recordemos que las frases válidas y más lógicas eran  LOS ALMACENES DE LOS ARTÍCULOS y LOS ARTICULOS DE LOS ALMACENES  plural-plural ) que nos permitirán navegar desde la tabla de Almacenes hasta la de artículos y viceversa.

Hemos de tener en cuenta que , si existen distintos punteros por los que navegara para moverse por las disitintas tablas, esto indica que desde una tabla se puede acceder a los datos de la otra. Es decir, desde Almacenes, puedo navegar al histórico de Existencias, para ver los Artículos que contine, y al revés, desde Artículos puedo navegar al histórico de Existencias para luego navegar por el maestro Almacenes

A %d blogueros les gusta esto: