v7 – Enlaces a hermano y saldos acumulados

Uno de los problemas más comunes que nos podemos encontrar en las aplicaciones de gestión es el arrastre de saldos como ocurre en los inventarios basados en Kardex, libros mayores contables y flujos de caja, en este post voy a pasar a detallar metodología que uso en mis aplicaciones para solventar dicho problema.

Caso de estudio:

Para hacer la explicación más práctica abordemos el caso de una tabla de libro mayor contable que almacene por año, mes, tercero y cuenta  los saldos y movimientos:

saldos

Punteros y el indice HERMANO:

Quien haya trabajado con punteros a hermano en Velneo sabe que el éxito de la implementación depende de una clara definición del indice que se usara para indicar cuales registros son “hermanos” entre sí, en nuestro caso tenemos un indice llamado “HERMANO” que agrupa los indices por los que queremos realizar el arrastre => Cuenta (PUC), Tercero (Comercial), Año y Mes;  la importancia de este orden radica en que queremos que sean considerados como “hermanos” los registros que compartan la misma cuenta y tercero y que al recorrer dicho indice sea haga en orden por año y mes, esto ultimo para hacer más eficiente el código de actualización que veremos adelante.

Con el indice claramente definido simplemente creamos los punteros que relacionaran los registros entre si, “PREV” apuntará al registro anterior usando el indice HERMANO, con 2 partes comunes y dirección “hacia atras”, misma lógica para el puntero “NEXT”

Valores Iniciales:

Para establecer los valores iniciales cuando se crea un nuevo registro es bastante simple: en el evento “anterior al alta” vamos a establecer como valor inicial para “SALDO_ANTERIOR” el saldo final del movimiento anterior:

Modificar campo(#SALDO_ANTERIOR, #PREV.SALDO_FINAL)

en cuanto al saldo final no es más que indicar en su valor inicial:

#SALDO_ANTERIOR + #DEBITO – #CREDITO

Hasta aquí todo es bastante simple si todos lo registros simplemente se crearen en periodos posteriores y no hubieran ni modificaciones ni eliminaciones de registros anteriores, pero usualmente las cosas no son tan simples así que tenemos que considerar que debe suceder en cada caso.

Escenarios a considerar:

1) El alta se da para un periodo intermedio y hay que actualizar los registros hacia adelante

2) En un registro pre existente se modifica el Saldo Ini, débito o crédito y ello afecta los saldos iniciales y finales de los periodos posteriores.

3) Se da una eliminación de un periodo intermedio y los registros posteriores deben ser actualizados.

en primera instancia antes de abordar estos casos necesitamos de un proceso de re cálculo de saldos que sea capaz de actualizar el valor de saldos iniciales y finales en un intervalo determinado de periodos:

El proceso CALCULAR_SALDOS_MAYOR

Este es un proceso con origen ficha de la tabla MAYOR, cuya función actualizar el saldo inicial de los registros posteriores al registro dado:

proceso

La búsqueda:

Esta búsqueda se encarga de encontrar los registros posteriores a una determinada fecha, relacionados con una cuenta y tercero.

Busqueda

Resolviendo los casos:

1) El alta se da para un periodo intermedio y hay que actualizar los registros hacia adelante.

Aquí simplemente debemos verificar en el evento posterior al alta si hay más registros hacia adelante y de existir actualizar sus saldos para que los movimientos del registro recién creado sean tenidos en cuenta , para ello en el evento “posterior al alta”:

posterior_alta

2) En un registro pre existente se modifica el Saldo Ini, débito o crédito y ello afecta los saldos iniciales y finales de los periodos posteriores.

El procedimiento en este caso es verificar si el débito, crédito o saldo anterior han sido modificados para proceder a actualizar los registros posteriores si es que existen, teniendo en cuenta que la variable RECALCULAR_MAYOR evitará que este mismo evento se ejecute durante el proceso de re cálculo de saldos y evitar así un loop

posterior_modificacion

3) Se da una eliminación de un periodo intermedio y los registros posteriores deben ser actualizados.

Para las eliminaciones lo que se debe hacer es posterior a que se realice la baja es actualizar el saldo anterior del registro inmediatamente posterior al registro que ha sido eliminado.

anterior_baja

y eso eso todo, ahora tienes saldos acumulados que son capaces de manejar altas, modificaciónes y bajas.

Es estable ?

Si bastante, esta metodología la he usando en diferente tablas con data de producción y cuando han habido discrepancia siempre han sido otros tipos de errores no de re calculo de saldos, por otro lado en este caso particular de la tabla MAYOR el proceso ha sido probado con vSpec (mi aplicación para automated tests) con tantos casos como se me han ocurrido.

15 thoughts on “v7 – Enlaces a hermano y saldos acumulados

  1. Hola Cristian:

    Un apunte. En el proceso “CALCULAR_SALDOS_MAYOR” la búsqueda que lanzas en el manejador de objeto, se realizará en primer plano. Solo se pueden lanzar en tercer plano con el manejador procesos.

    En tu caso, las instrucciones que hace referencia a la búsqueda, mételas en otro proceso “CALCULAR_SALDOS_MAYOR_3P” y llama a ese proceso desde un manejador en el proceso “CALCULAR_SALDOS_MAYOR” pasándole las mismas variables.

    Un saludo

    1. Hola Fran,

      pues hasta donde sé cualquier proceso ya sea por manejador de objetos o “ejecutar proceso” que se corra desde un trigger correrá en 3r plano por defecto, hasta donde entiendo tu apunté seria valido si estuviera llamando dicho proceso mediante una acción o algún proceso en 1-2 plano,

      si estoy equivocado me corriges por favor, para realizar las correcciones de caso.

      Gracias,

      1. Hola Cristian:

        Disculpa… no vi que lo lanzabas desde un trigger… Aún así no tengo claro que al cruzar los indices se lancen en tercer plano.

        Si ese mismo proceso lo lanzas en primer plano, la búsqueda se lanzaría en tercer plano….Lo que se lanzaría en primer plano serían los distintos componentes de la búsqueda, es decir… pedirías la búsqueda… devolvería los registros… volvería a pedir al servidor el segundo componente… devolvería los registros… volvería a pedir al servidor el tercer componente… etc etc.

        Por cierto, trata de evitar los “Filtrados de lista”, “Ordenar Lista”, etc etc

        Un saludo

  2. Hola Cristian:

    Yo tengo ese montaje pero he experimentado problemas cuando, como en el caso 1, se hace una modificación en un registro antiguo que tiene que actualizar saldos hacia adelante. En algunas ocasiones se rompe el vServer. ¿Te ha pasado algo parecido?

    1. Pues yo hice pruebas con registros contables de 1 año completo modificando datos en enero y al ppio rompía el vServer porque las actualizaciones de valores las realizaba dentro de los triggers y claro al haber tantas fichas se producía un efecto en cascada de triggers de modificación, por ello cambie a un proceso más lineal (proceso + búsqueda) y a usar un semáforo con la variable global, como resultado el proceso quedó más rápido al ser uno solo sin disparar eventos y no se producían esas actualizaciones en cascada.

      Un saludo

      1. Ok, entendido. Sí, efectivamente yo tengo triggers que fuerzan la actualización del hermano siguiente en cascada. En Velneo 6.x nunca tuve ningún problema, aunque quizás nunca lo utilicé con tantos datos. Lo replantearé, gracias por el tip.

        Un abrazo.

  3. Hola, muy buena aportación, pero tengo un par de dudas.
    La variable RECALCULAR_MAYOR que tenemos en el proceso, entiendo que tiene que tener persistencia en disco, no?, de ser así, si tenemos varios usuarios introduciendo datos, mientras el proceso esté activo, los registros de los demás usuarios nunca actualizarán los datos, por lo que se pierde el arrastre de acumulados.
    Igual se me escapa algo.
    Saludos, Luis

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s