Descripción técnica de GestiONG.
¿Qué características
mínimas debe proporcionar un programa de gestión?
A mi modo de ver, un programa de gestión debe proporcionar lo siguiente
al usuario final:
- Un programa completo de contabilidad adaptado al plan contable vigente.
- Cuentas, asientos y apuntes, tipos de asientos y conceptos
de apunte.
- Libros de IVA.
- Seguridad de que las operaciones se graban correctamente.
- Posibilidad de manejar múltiples empresas y ejercicios.
- Un nivel de seguridad que obligue a identificarse como usuario y que
permita definir qué operaciones puede o no puede hacer cada usuario.
Además, debe proporcionar la posibilidad de guardar un registro de
todas las operaciones que realicen los usuarios.
- Posibilidad de definir los nombres de los ficheros y de los campos
de cada fichero, la longitud de los mismos, su formato, etc y además
que se pueda definir de forma diferente para cada usuario.
- Una definición de las bases de datos que haga posible efectuar
copias de seguridad fácilmente y que se ajuste a la Ley Orgánica
de Protección de Datos de carácter personal.
- Imposibilidad de introducir datos incorrectos o inconsistentes, como
fechas no válidas, letras en vez de números, asientos sin apuntes,
etc.
- Posibilidad de comprobar la integridad de los datos, con posibilidad
de corregirlos si hay errores.
- Ayuda sensible al contexto y enlaces a páginas en internet con
información contable.
¿Qué se
necesita para realizar un programa de gestión bajo GNU?
Una base de datos.
Este es el requisito menos complicado. Existen dos servidores
de bases de datos SQL de uso libre, PostgreSql con licencia BSD y Mysql de uso libre aunque con licencia
propietaria.
Un lenguaje orientado a objetos.
Un programa de estas características es un programa que
puede tener facilmente una treintena de formularios de mantenimiento de
ficheros de la base de datos. El funcionamiento de ellos es básicamente
idéntico, por lo tanto, es imprescindible diseñar un formulario
base con toda la funcionalidad y derivar el resto de formularios a partir
de él. Así, cualquier modificación que haya que hacer
en todos los formularios de mantenimiento, solo hay que realizarla en el
formulario base. Este objetivo lo he logrado con C++ y Qt Designer.
Un IDE decente con una depuración decente.
KDevelop como editor deja mucho que desear, para grandes ediciones
uso emacs, pero como depurador es muy fácil de usar y funciona muy
bien. La opción de búsqueda en ficheros está muy bien.
La versión 3.0 de KDevelop promete ser muy buena.
Generación automática de código
Manejar una treintena de ficheros de la base de datos es una
tarea muy costosa. Diseñar una treintena de formularios, una treintena
de clases para leer y grabar en la base de datos, una treintena de entradas
en el menu, una doble treintena de informes, etc es una tarea imposible durante
una vida humana sin una herramienta de generación automática
de código. Y lo que es peor, cualquier adición o supresión
de un simple campo en una base de datos implica un montón de trabajo
y de pruebas y, por supuesto, de errores.
En este punto, mi herramienta de generación de código
lee la definición del fichero de la base de datos que está
en un fichero XML y me genera el fichero .ui del Qt Designer, para que yo
lo revise después y lo deje bonito, me genera el código del
formulario que he dejado bonito con el Qt, me genera la clase para leer y
escribir en la base de datos, me genera las entradas en el menu, la documentación
y un montón más de cosas, prácticamente todo lo que
tiene que ver con esa tabla. Además, puede regenerarlo cada vez que
hago un cambio en la base de datos y todo se actualiza automáticamente.
De este modo, añadir una nueva tabla a la base de datos con su formulario
y todo funcionando perfectamente me ocupa solo unas tres horas.
Un diseñador de formularios flexible, cómodo y que
permita modificar el código generado.
Qt Designer es uno de los mejores diseñadores de GUIs
que he probado. (Cuando pongo un control en un sitio, se queda ahí
:)
Unos controles de edición personalizados.
Para que el el programa sea ágil de manejar y la presentación
de datos en pantalla sea clara, es necesario retocar todos los controles
de edición, como líneas de texto, botones, listas, combos,
etc. La redefinición de estos controles standard de la biblioteca
Qt es tan fácil como crear una nueva clase derivada y cambiar algunos
métidos y propiedades.
La validación de datos es muy importante en este tipo de programas
en los que la información que se trata es de vital importancia.
Por lo tanto, el programa debe permitir que los datos, por ejemplo una
fecha, se introduzcan de forma rápida y sin ambigüedades y
además que se tenga la certeza de que siempre son correctos. Por
lo tanto, el control más importante es el que permite la introducción
de números, fechas, cadenas con formato, horas, cantidades monetarias,
etc. Este control es el IMaskedLineEdit y tiene las siguientes propiedades
más destacadas:
- Edición con máscaras de números, fechas,
horas, cadenas con formato y cantidades monetarias.
- Avance y retroceso con Intro y las teclas del cursor.
- Diferenciación visible de cuando es editable y cuando
no.
- Validación de los datos sin permitir que el cursor salga
del control si los datos no son válidos.
Un formulario base para los mantenimientos de las bases de datos
Este formulario se debe encargar de mostrar una lista con los
datos del fichero y una vista de edición de un registro individual.
Se debe encargar de leer de la base de datos, de mostrar los botones para
añadir, borrar, etc... y de hacer que funcionen. Véase FrmEditRecBase
y FrmEditRec.
Un generador de Informes
Este es hasta ahora el mayor problema, aunque ya he comenzado
con el diseño de uno. No he encontrado ninguna herramienta de diseño
de informes que tome datos de una base de datos SQL y genere un informe
decente, en el que puedas hacer sumas, grupos, fórmulas, etc.
Este proyecto tardará un poco más, pero con la ayuda
de la generación automática de código, quién
sabe...
¿Cómo
está organizado GestiONG?
GestiONG se está desarrollando en C++, bajo Linux y con
soporte de la biblioteca Qt 3.x
El programa puede separarse en tres niveles:
- Nivel de acceso a la base de datos.
- Nivel de aplicación
- Nivel de Interfaz gráfica de usuario.
La parte más difícil del programa es la Interfaz Gráfica
del Usuario, aunque la biblioteca Qt junto con Qt Designer hacen esta parte
menos complicada. El acceso a las bases de datos es muy fácil también
gracias a la biblioteca Qt. El nivel de aplicación es muy sencillo,
pues un programa de contablidad realmente no tiene grandes procesos.
Actualmente no hay separación en proyectos de estos tres niveles,
ya que la etapa de desarrollo en la que estamos es aún muy temprana.
No obstante, más adelante será totalmente necesario separar
estos niveles en distintos proyectos.
Nivel de acceso a la base de datos.
Para ver la definición de la base de datos, véase 'dictionary.xml'
El programa está diseñado de forma que se pueda manejar con
cualquier servidor de base de datos. Actualmente funciona con MySQL y PostGreSQL.
El acceso a las bases de datos es muy fácil con Qt. Se han creado
una serie de clases para encapsular las de Qt y añadirles algunas
funciones útiles.
- ISqlDatabase. Encapsula QSqlDatabase.
- ISqlQuery. Encapsula QSqlQuery.
- ISqlRecord. Esta clase representa un registro de una tabla. No se
utilizan las clases de Qt para edición de registros generales, como
QSqlCursor o QSqlRecord. La razón es que éstas tratan los registros
y campos sin conocer su tipo, lo que puede dar lugar a errores y además
es menos eficiente. Yo he optado por crear una clase por cada tabla en la
que los campos están bien definidos. Como esto sería muy trabajoso
de hacer a mano, he creado un programa que genera estas clases automáticamente,
basándose en la definición de la base de datos que se almacena
en el fichero 'dictionary.xml'. Por ejemplo, /forms/reccuenta.h y /forms/reccuenta.cpp.
- ISqlError. Encapsula QSqlError.
De este modo, la lógica de acceso a una tabla de la base de datos
es así:
- Conectar con el servidor.
- Crear un objeto RecCuenta, que es un ISqlRecord que contiene toda
la información del registro de la tabla 'cuenta'.
- Leer un registro, con RecCuenta::read(ID).
- Leer los campos con RecCuenta::getNOMBRECUENTA() y escribirlos con
setNOMBRECUENTA("Mercaderías");
- Grabar los datos con RecCuenta::save();
- Borrar con RecCuenta::remove();
Nivel de aplicación
Este nivel está totalmente mezclado con el GUI, debido a las características
de la aplicación. No obstante, hay algunas clases que se consideran
básicas y que se pueden definir independientemente del interfaz gráfico:
- Cuenta. Operaciones como comprobar la validez, comprobar si las cuentas
padres existen, obtener una nueva cuenta de trabajo para un grupo, la siguiente
cuenta, etc.
- Plancontable Definición de la estructura en niveles del plan
contable.
- Cif. Operaciones como comprobar la validez, calcular la letra del
NIF, etc.
Nivel de interfaz gráfica de usuario (GUI).
Se puede decir sin ningún reparo que el 90% del desarrollo del programa
consiste en pelearse con el GUI. La parte más complicada consiste en
que los formularios de introducción de datos funcionen de la forma
que esperamos. Por ejemplo, que la tecla INTRO y el CURSOR ABAJO avancen al
siguiente campo, que el cursor no pueda salir de un campo si los datos no
son correctos, que la tecla ESCAPE anule la edición pero antes muestre
un mensaje de confirmación, que algunos formularios sean modales, etc.
No sé exactamente por qué, pero tanto Qt como GTK no proporcionan
esto de forma fácil, ni mucho menos predefinida. No obstante, con Qt
al menos se puede conseguir, aunque hay que estar constantemente investigando,
y aquí es donde se demuestra la principal ventaja del software con
licencia GPL, se puede consultar el código fuente para ver cómo
funciona la biblioteca Qt y hallar una solución.
El programa GestiONG se puede simplificar considerándolo como la
edición de los ficheros de la base de datos. De este modo, casi todas
las operaciones que se realizarán sobre el fichero de cuentas será
su mantenimiento, esto es, altas, bajas, modificaciones, consultas, búsquedas,
etc. Por lo tanto, el diseño de un formulario básico para realizar
el mantenimiento de los ficheros de forma unificada y completa es fundamental
y además nos completa más de la mitad del programa. Este formulario
es el FrmEditRec, que proporciona una ventana en la que mostrar los campos
del fichero y toda la lógica para leer, editar y grabar los datos.
A partir de este simple formulario, se derivan :
- FrmEditRecMaestro: Añade una lista para hojear todos los registros
del fichero con opciones para filtrar y buscar registros, y el resto de operaciones
sobre el registro, como borrar, duplicar, añadir, imprimir, etc.
- FrmEditRecMaestroDetalles: Añade la lógica para editar
un fichero maestro con un fichero de detalles.
- FrmEditRecDetalle: Formulario simple para editar un detalle bajo el
auspicio de un FrmEdiRecMaestroDetalles.
¿Qué ventajas y qué inconvenientes presenta
Linux como plataforma de desarrollo?
Ventajas:
- Acceso al código fuente de las herramientas y bibliotecas con las
que se trabaja.
- Gratuidad de estas mismas herramientas y bibliotecas.
- Ayuda por parte de la comunidad de desarrollo.
- Disponibilidad de herramientas de tratamiento de ficheros de texto, como
sed, diff, patch, tar, etc. muy útiles en algunas ocasiones.
- Disponibilidad nativa de CVS.
Inconvenientes:
- Poca estabilidad del entorno de desarrollo, principalmente del editor.