Entrada de contabilidad duplicada en una base de datos relacional

De un traductor : durante mi trabajo en el fintech nigeriano tuve que crear un sistema de pago desde cero. En ese momento, realmente no entendía nada sobre contabilidad, en cuanto a cómo es mejor almacenar pagos y saldos. Pero se sospechaba que la opción primitiva con un dígito de saldo en la cuenta del usuario es demasiado simple para ser correcta.


Este artículo me ayudó a comprender y evitar un montón de rastrillos en este asunto. Al mismo tiempo, la información sobre el tema "cómo hacer su propio sistema de pago" es bastante pequeña, y no es tan fácil (y muy tedioso) comprender los libros de texto sobre contabilidad para un programador de inmediato. Espero que este material sea útil para aquellos que solo van a hacer algo como esto.


Inmediatamente pido disculpas por posibles imprecisiones en términos financieros de habla rusa: sigo siendo un programador, no un contador, y no estoy familiarizado con la terminología rusa en esta área.


Introduccion


Muchos sistemas informáticos que utilizan bases de datos relacionales almacenan algún tipo de información financiera sobre saldos y transacciones. Además, el diseño y desarrollo de dicha base de datos a menudo plantea la cuestión de cómo almacenar esta información. Por lo general, la elección es entre una "grabación simple" barata y una "grabación doble" más compleja.



Luca Pacioli, autor del libro sobreviviente más antiguo (siglo XV) que describe los principios de la doble entrada.


En un sistema de "registro simple", los valores numéricos se registran solo una vez. En un sistema de doble entrada, cada valor se registra dos veces como crédito (valor positivo) y como débito (valor negativo). Hay un conjunto de reglas que determinan la relación entre estos valores. Cualquier contador experimentado le describirá fácilmente estas reglas, aunque tal vez ni siquiera se imagine cómo pueden representarse en una base de datos relacional.


Las reglas básicas son las siguientes:


  1. Cada entrada en el sistema debe estar equilibrada, es decir la suma de todos los valores en una operación debe dar cero.
  2. La suma de todos los valores en todo el sistema en cualquier momento dado debería dar cero (la regla del llamado "balance de prueba").
  3. Los valores ya ingresados ​​en la base de datos no se pueden editar ni eliminar. Si las correcciones son necesarias, la operación debe cancelarse primero por otra operación con el signo opuesto y luego repetirse con el valor correcto. Esto le permite implementar un seguimiento de auditoría confiable (un registro completo de todas las transacciones, a menudo requerido durante las inspecciones).

Aplicabilidad de doble contabilidad


Al comienzo de un proyecto, el bajo precio de una grabación simple siempre es tentador, y el costo de implementación y la complejidad de una grabación doble completa parecen innecesarios. Sin embargo, en realidad, a menudo usar una grabación simple es un falso ahorro.


Si la información contable en el sistema de TI solo copia los registros en papel existentes almacenados fuera de la base de datos que se está desarrollando, entonces un registro simple todavía tiene derecho a la vida. Sin embargo, si al menos uno de los hechos sobre el sistema que se enumera a continuación es verdadero, entonces se debe usar una entrada doble desde el principio:


  1. Si alguna vez se requiere una auditoría contable de la información
  2. Si la información en el sistema es la única fuente de información sobre la propiedad
  3. Si la información se refiere a objetos de alto valor
  4. Si se planea que el sistema se desarrolle seriamente en el futuro

Ejemplo de doble entrada


La idea clave de la doble entrada es la existencia de una cuenta especial "libro de caja" ( aprox. Traducción: no encontré cómo llamarlo adecuadamente en ruso, ¿alguien me lo puede decir? ). Esta cuenta contiene registros realizados cuando los objetos de valor (como dinero) se depositan o retiran de nuestro sistema de contabilidad. Por lo tanto, el saldo actual de esta cuenta refleja el número total de valores en el sistema.


El siguiente es un ejemplo simple con dos cuentas, "libro de caja" y "Smith".


(a) Se ingresan £ 300 en el sistema y se depositan en la cuenta de Smith. Se crea un préstamo de £ 300 en la cuenta de Smith (crédito a la derecha, débito a la izquierda). Para nivelar esta cantidad, se crea un débito de £ 300 en la cuenta del libro de caja.



(b) Smith deduce £ 50 del sistema. Creamos un débito por este monto en la cuenta de Smith y un crédito en el libro de caja.



(c) Agregue otra cuenta de Pattel y transfiérale 100 £ de Smith. Para hacer esto, necesitamos crear un débito por esta cantidad con Smith y un préstamo con Pattel.


(d) Como toque final, dejemos que Pattel retire ahora £ 60 del sistema. Creamos un débito en su cuenta y un crédito en el libro de caja.



Como resultado de todas estas operaciones, podemos calcular que el saldo total de Smith es de 150 £, Pattela 40 £, y en el Libro de caja -190 £, la suma negativa de los saldos de todas las demás cuentas. Sobre la base de estas reglas y operaciones simples en el futuro, puede crear un sistema de control de valor muy completo.


Modelo de datos


La estructura de un modelo de datos simple que se puede utilizar para representar toda esta información:



La tabla POSTING contiene las entradas dobles en sí. Almacenar todos los números en una tabla simplifica enormemente todos los cálculos. Se debe utilizar un contador monotónicamente creciente como clave principal. Los valores deben ir en una fila, en este caso, por el número, siempre puede asegurarse de que no se haya eliminado ningún registro. Las tablas BATCH y JOURNAL se usan para controlar e ingresar datos en esta tabla POSTING.


Cada entrada en la tabla DIARIO representa una transacción (desde una perspectiva comercial) que genera entradas dobles. Dicha transacción es una unidad de trabajo completa o un proceso comercial. O bien todos los registros de PUBLICACIÓN asociados con el registro DIARIO deben completarse con éxito, o ninguno de ellos. La suma de todos los registros de PUBLICACIÓN en una sola transacción debe ser cero. Cada operación de transferencia del ejemplo anterior está representada por su entrada en la tabla DIARIO


La entrada en la tabla BATCH se realiza para la conveniencia de la entrada de datos. Se utiliza para agrupar registros de DIARIO en paquetes convenientes, por ejemplo, un conjunto de comprobaciones para ingresar al sistema, algún tipo de proceso comercial global, como cobrar intereses a todos los usuarios a la vez, etc.


La tabla CUENTA almacena datos sobre los propietarios de valores en el sistema.


La tabla ASSET TYPE contiene información sobre los tipos de valores utilizados en el sistema. Al agregar un tipo de valor a la clave principal de la tabla POSTING, puede crear un sistema que funcione con varios tipos de valores a la vez (por ejemplo, procesando varias monedas).


Así es como una base de datos de este tipo podría buscar el ejemplo anterior en la forma más simplificada:



El saldo de la columna Cantidad en la tabla PUBLICACIÓN siempre es cero después de completar cualquier transacción de JOURNAL (el software debe asegurarse de que no haya registros de transacciones incompletas en la base de datos).


La suma de las operaciones para la cuenta del Libro de caja da -190, que es igual a la suma de los saldos de Smith y Pattel con el signo opuesto.


Para demostrar la operación multidivisa, se ha agregado un nuevo tipo de valor. Si Smith quiere cambiar 20 libras por dólares a razón de 1 por 1.5, la transacción se realizará a través del Libro de caja de esta manera:



Períodos de facturación


El modelo que obtuvimos se ve muy bien, pero en realidad se romperá muy rápidamente bajo una gran carga debido al hecho de que no podemos eliminar nada y nos vemos obligados a contar constantemente el número cada vez mayor de registros en PUBLICACIÓN.


La mayoría de los sistemas de contabilidad tienen el concepto de un período de facturación, generalmente un mes, tres meses o un año. Tal período sugiere puntos convenientes para dividir el flujo de datos. Por lo general, un punto conveniente es el final del año, calendario o financiero.


Podemos agregar una columna con un indicador de período a la tabla POSTING y a su clave principal, dividiendo los datos en grupos que se pueden procesar de forma independiente. Si en el ejemplo anterior algunos de los registros cayeron en un nuevo período de facturación, los saldos de las cuentas se traspasarían de la siguiente manera.


Primero, los saldos del período anterior se compensarían.


imagen


Y luego serían transferidos a un nuevo período



Después de cierto tiempo, todos los registros del período AÑO 1 pueden enviarse al archivo y eliminarse del sistema sin perder su integridad.


Agregación de transacciones


Algunas operaciones en el sistema de contabilidad pueden afectar a muchos o incluso a todos los usuarios a la vez. Por ejemplo, los pagos de intereses a todos los usuarios en forma de una parte de su saldo actual.


Dichas operaciones pueden procesarse como parte de una sola transacción en la tabla DIARIO y puede agregar todas las operaciones con el Libro de caja en un registro común en la tabla PUBLICACIÓN (en lugar de crear una operación separada para cada cuenta). Esto le permitirá cumplir con todas las reglas de contabilidad anteriores y al mismo tiempo reducir a la mitad el número de registros en la base de datos. Con este enfoque, el final del año en la base de datos se verá así:



Procesamiento por lotes


El procesamiento por lotes a menudo se usa para simplificar la entrada de datos en el sistema de contabilidad.


Históricamente, el procesamiento de cheques ha funcionado así. El contador recibió un paquete de diez cheques, el número del paquete y la cantidad total de todos los cheques. En la primera etapa, los cheques se ingresan en el sistema en forma de entradas "no autorizadas". En este caso, a través de la tabla BATCH, se verifica su cantidad y la cantidad total, y solo si coinciden con el valor correcto, el usuario puede confirmar el paquete. Una vez hecho esto, el paquete se envía a otro empleado que verifica su validez y luego "autoriza" si todo se ingresó correctamente.


Este proceso se llama "fabricante / verificador" y se puede utilizar para ingresar cualquier información relevante en el sistema.


En este caso, los registros "no autorizados" en una tabla separada del conjunto principal de registros dobles en la tabla PUBLICACIÓN serán correctos. También puede tener varias tablas de este tipo para diferentes procesos empresariales. Por ejemplo, en el caso de cheques a través de los cuales se ingresa o retira dinero del sistema, el contador solo tendrá que verificar una cuenta. Desde el segundo, Libro de caja, en tales operaciones siempre está implícito. En este caso, en la tabla CHECK será posible administrar solo una columna con la cuenta, mientras que en la tabla hipotética TRANSFERENCIA DE FONDO se necesitarán dos columnas: "remitente" y "destinatario".


Aquí es donde surge el malentendido básico de los principios de la doble grabación. La mayoría de las personas en la vida cotidiana se encuentran con simples libros de contabilidad en papel. En tal libro de papel, por ejemplo, para contabilizar las finanzas de un determinado club de interés, solo necesita una entrada para cada operación. Sin embargo, todavía tiene una doble entrada implícita, ya que siempre hay una cuenta implícita en el Libro de caja (en este caso, este es el club), porque todos los flujos de efectivo siempre son de entrada (pago de tarifas por parte de los participantes) o retiro de dinero del sistema (gasto club).


La segunda razón para los conceptos erróneos es que en los estados de cuenta personales el dinero depositado en la cuenta se considerará un "préstamo", porque una persona esencialmente presta a un banco que recibe su dinero. Aunque si esta persona mantuviera su libro mayor, esta entrada se habría registrado como "débito", ya que el banco le debe este dinero a su cliente. Este dinero se retira del "sistema de pago" del usuario y se ingresa en el sistema bancario.


Arquitectura de software


El software que implementa un sistema de contabilidad de doble entrada se desarrolla mejor utilizando OOP y un enfoque escalonado. Los niveles son los siguientes:


  1. Interfaz externa
  2. Lógica de negocios
  3. Trabajar con un DB

Por supuesto, la arquitectura del sistema dependerá de lo que debe hacer exactamente este sistema, sin embargo, podemos asumir la presencia de los siguientes módulos:


PostEntry: un módulo que controla la creación de entradas dobles en la tabla POSTING. Es responsable de insertar registros, asignar identificaciones y marcas de tiempo. El módulo no puede eliminar ni modificar registros y ningún otro módulo debe eliminar o modificar estos registros, excepto la posible eliminación de registros archivados antiguos para períodos de facturación ya irrelevantes. La tabla POSTING debe ser de solo lectura para todos los demás módulos.


MakeDeposit, MakeWithdrawal, MakeTransfer: estos módulos implementan la lógica comercial básica para las operaciones de transferencia de fondos. Utilizarán el módulo PostEntry para ingresar sus resultados en la base de datos.


ChequeEntry y ChequeAuthorisation, ReceiveBACS ( nota: BACS es un sistema de pago interbancario ): estos módulos conectarán el sistema con el mundo exterior y proporcionarán una interfaz de alto nivel. Utilizarán los módulos de capa empresarial para realizar sus funciones. En este caso, puede garantizar el procesamiento correcto independientemente del método de entrada de datos, ya que ChequeEntry y ReceiveBACS funcionarán a través del mismo MakeDeposit


Esta metodología para separar capas se puede aplicar en mayor o menor medida, dependiendo de la complejidad del sistema y la pureza deseada de usar los principios del diseño de objetos. Al mismo tiempo, podría tener sentido, por ejemplo, permitir que el módulo de generación de informes (por ejemplo, TestTrialBalance) acceda directamente a la base de datos desde el nivel de la interfaz, en lugar de crear módulos intermedios en las capas empresariales y de base de datos.



Balance de prueba


"Balance de prueba": la forma principal de verificar la integridad del sistema contable. Si todas las entradas se ingresaron en el sistema de acuerdo con las reglas de doble entrada y no hubo errores, entonces la suma de todas las entradas debería ser cero. La probabilidad de que varios errores separados se sumen y den un total de cero en una base inválida es generalmente tan pequeña que se descuida.


La mejor manera de verificar es un movimiento constante desde el nivel superior al inferior. Los controles tienen sentido en este orden:


  1. La suma de todos los valores en la columna POSTING.Amount
    Si se encuentra un error (el valor no es cero), entonces:
  2. La suma de todos los valores POSTING.Amount, pero calculados por separado para diferentes tipos de valores y períodos de liquidación
    En esta etapa, debería quedar más claro en qué parte del sistema se produjo un error.
  3. Comprobación de operaciones individuales en la tabla DIARIO. Dado que la suma de todas las CUENTAS DE PUBLICACIÓN en cada transacción de la tabla DIARIO también debe dar cero, entonces puede realizar un seguimiento de la transacción problemática específica.

DIARIO tipos de publicación


La tabla JOURNAL contiene una representación simple de entidades, que, sin embargo, a menudo demuestran ser más complejas e involucradas en diversas relaciones.


A veces tiene sentido dividir una tabla en varias. Por ejemplo, en MATERIALIZADO y DESMATERIALIZADO, que puede tener un conjunto diferente de columnas, por ejemplo, las entidades materiales pueden requerir datos sobre su ubicación actual.


O, en una tabla, se pueden almacenar diferentes subtipos de valores, como moneda o valores, cada subtipo puede tener su propio conjunto de propiedades y atributos.


Las entidades que tienen subtipos y supertipos se pueden organizar en la base de datos de una de cuatro maneras (esta es una situación bastante estándar para cualquier base de datos):


  1. Una tabla grande común con muchas columnas opcionales para atributos de subtipo
  2. Tabla separada para cada subtipo, con duplicación de todas las columnas comunes.
  3. Separe las entidades para que el supertipo se almacene en una tabla separada y se una con otras tablas que contengan solo columnas específicas de subtipo
  4. Igual que en 3, pero con duplicación de columnas de supertipo en tablas de subtipo

Cada una de las cuatro opciones tiene sus ventajas y desventajas. Desde un punto de vista de doble entrada, es útil tener una tabla común para entradas de PUBLICACIÓN. La opción 1 es más adecuada para un sistema de contabilidad simple (como en los ejemplos de este artículo, donde la única diferencia en los tipos de valores está determinada por la columna JOURNAL.Type). La opción 3 probablemente sea más adecuada para sistemas complejos que funcionan con una amplia gama de valores muy diferentes.

Source: https://habr.com/ru/post/480394/


All Articles