Cuando Nexus habla…
…el sabio escucha.
“Ah, maestro, ¿cómo puedo escuchar a Nexus y unirme a él en el cosmos?” imploró el inexperto novicio.
“Programa, únete a Nexus y la verdad te será revelada, como junco mecido por la brisa en una suave mañana de primavera”, contestó el maestro.
“Yo programo en VB6, maestro” continuó el novicio.
Tras un momento de profunda meditación, el maestro dijo: “…y te haces tus propios juegos, ¿verdad?”, mientras le sacudía con la escupidera de bronce.
Hay momentos en la vida de todo distribuidor que llega ese cliente, sí, ese cliente que quiere algún comportamiento especial (y no me refiero ni a flores, ni diamantes ni cualquiera de esas cosas del día de los empanados) a la hora de trabajar con Nexus. Para ello disponemos de la posibilidad de escuchar eventos del nexus cuando realiza determinadas operaciones, permitiéndonos cancelarlos, alterarlos o complementarlos.
Lo primero, sería conocer qué podemos escuchar…
Una pequeña lista:
- Cargar y descarga de nuestra DLL
- Antes y después del guardado de:
- Maestros.
- Documento.
- Líneas de documento.
- Remesas.
- Efectos.
- Apuntes (solo nos avisa del “antes de guardar”).
- Asientos.
Salvo el caso de los apuntes (en los que solo nos avisará antes de guardar), se nos notificará antes y después de guardar el elemento del tipo en cuestión.
¿Cuál es la finalidad de que nos avisen del “antes” y “después” de guardar?
Su finalidad es clara, es facilitar las implementación, por parte de nuestros distribuidores, de reglas de negocio.
Antes de:
Así, en las notificaciones “antes de” suelen utilizarse para realizar las validaciones adicionales que se quieran realizar sobre un elemento dado. Tengamos en cuenta el significado de “antes” en su sexta acepción. Todavía el elemento no se ha almacenado, por lo que si realizamos alguna acción o tarea que suponga que el elemento se ha guardado podemos estar introduciendo un error en nuestras nuevas reglas. Más aún, en las últimas versiones se pueden alterar valores del elemento que se está guardando. Con esto lo podemos alterar al gusto del cliente, pasando por encima de los cálculos y valores por defecto que el nexus imponga.
Después de:
Llegada esta notificación, el elemento está almacenado en nuestra base de datos. Se nos da así la oportunidad de completar el guardado con nuestras propias acciones adicionales (también, por supuesto, es otra oportunidad para modificarlo, vía NAX, pero es ralentizar el proceso teniendo el “Antes de”). Lo que JAMÁS se debe hacer es modificar el elemento “a mano” directamente en la base de datos.
Listado de eventos
Y finalmente aquí está el listado de eventos (primero con sintaxis delphi y luego en c#) con los que podemos escuchar a Nexus:
//Sistema Iniciar: procedure( Empresa: PChar); stdcall; IniciarConSistema: procedure( Empresa, Sistema: PChar); stdcall; Finalizar: procedure; stdcall; //Documentos DespuesDeGuardarDocumento: procedure(Documento: string; IdDoc: Double); stdcall; DespuesDeGuardarDocumentoV2: procedure(Documento: String; IdDoc: Double; Estado: Integer); stdcall; AntesDeGuardarDocumento: function(Documento: string; IdDoc: Double; var Cabecera: Variant; var Lineas: Variant): boolean; stdcall; AntesDeGuardarDocumentoV2: function(Documento: string; IdDoc: Double; var Cabecera: Variant; var Lineas: Variant; Estado:Integer): boolean; stdcall; AntesDeGuardarLinea: function(Documento: String; Cabecera: Variant; Linea: Variant): Variant; stdcall; AntesDeGuardarLineaConDetalle: function(Documento: String; Cabecera: Variant; Linea: Variant; Detalle: Variant): Variant; stdcall; DespuesDeGuardarLinea: procedure(Documento: String; Cabecera: Variant; Linea: Variant); stdcall; DespuesDeGuardarLineaConDetalle: procedure(Documento: String; Cabecera: Variant; Linea: Variant; Detalle: Variant); stdcall; //Cartera AntesDeGuardarEfecto: function( Operacion: string; Datos: Variant): boolean; stdcall; DespuesDeGuardarEfecto: procedure( Operacion: string; NumCartera: Double; NumVen: integer); stdcall; AntesDeGuardarRemesa: function( Operacion, Tipo: string; Cabecera, Lineas: variant):boolean; stdcall; DespuesDeGuardarRemesa: procedure( Operacion, Tipo: string; IdRemesa: Double); stdcall; //Maestros AntesDeGuardarMaestro: function(Tabla: String; Datos: Variant): Boolean; stdcall; AntesDeGuardarMaestroV2: function(Tabla: String; Datos: Variant): Boolean; stdcall; DespuesDeGuardarMaestro: procedure(Tabla: String; Datos: Variant); stdcall; DespuesDeGuardarMaestroV2: procedure(Tabla: String; Datos: Variant); stdcall; AntesDeBorrarMaestro: function( Tabla: string; IdMaestro: Variant): boolean; stdcall; DespuesDeBorrarMaestro: procedure( Tabla: string; IdMaestro: Variant); stdcall; //Apuntes AntesDeGuardarApunte: function( Apunte: variant):boolean; stdcall; AntesDeGuardarAsiento: function( IdAsiento: Double; Asiento: variant):boolean; stdcall; DespuesDeGuardarAsiento: procedure( IdAsiento: Double; Asiento: variant); stdcall;
//Sistema void Iniciar(string Empresa, string Sistema); void Finalizar(); //Documentos bool AntesDeGuardarDocumento(string Documento, double IdDoc, object Cabecera, object Lineas, int Estado); void DespuesDeGuardarDocumento(string Documento, double IdDoc); void DespuesDeGuardarDocumentoV2(string Documento, double IdDoc, int Estado); bool AntesDeGuardarDocumento(string Documento, double IdDoc, ref object Cabecera, ref object Lineas); bool AntesDeGuardarDocumentoV2(string Documento, double IdDoc, ref object Cabecera, ref object Lineas, int Estado); object AntesDeGuardarLinea(string Documento, object Cabecera, object Linea); object AntesDeGuardarLineaConDetalle(string Documento, object Cabecera, object Linea, object Detalle); void DespuesDeGuardarLinea(string Documento, object Cabecera, object Linea); void DespuesDeGuardarLineaConDetalle(string Documento, object Cabecera, object Linea, object Detalle); //Cartera bool AntesDeGuardarEfecto(string Operacion, object Datos); void DespuesDeGuardarEfecto(string Operacion, double NumCartera, int NumVen); bool AntesDeGuardarRemesa(string Operacion, string Tipo, object Cabecera, object Lineas); void DespuesDeGuardarRemesa(string Operacion, string Tipo, double IdRemesa); //Maestros bool AntesDeGuardarMaestro(string Tabla, object Datos); bool AntesDeGuardarMaestroV2(string Tabla, object Datos); void DespuesDeGuardarMaestro(string Tabla, object Datos); void DespuesDeGuardarMaestroV2(string Tabla, object Datos); bool AntesDeBorrarMaestro(string Tabla, object IdMaestro); void DespuesDeBorrarMaestro(string Tabla, object IdMaestro); //Apuntes bool AntesDeGuardarApunte(object Apunte); bool AntesDeGuardarAsiento(double IdAsiento, object Asiento); void DespuesDeGuardarAsiento(double IdAsiento, object Asiento);
Como se puede ver hay una pequeña diferencia entre Delphi (o cualquier lenguaje con el que podamos realizar dlls win32) y C# (o cualquier lenguaje que pueda crear objetos COM), es que en este último no existe el “IniciarConSistema”. En su lugar, “Iniciar” realiza el trabajo de aquella.
Una vez que conocemos que puede hacer Nexus por nosotros, solo nos queda usar un poco el cerebro y ver si podemos implementar alguna solución al problema que nos planteaba el cliente (ese que no nos ha traído flores, snif…).
Y esto es todo por hoy… en el próximo, entraremos en faena, pequeño saltamontes. Ahora ve a curar tus chichones.
Agradecimientos: A Luis (Solusoft) y Eduardo (I el Grande de SIE) por encontrar un error en la definición de las funciones AntesDeGuardarDocumento en C#.
Nota: Cualquier parecido entre las cabeceras de las funciones especificadas en esta entrada del blog puede ser pura coincidencia. Como referencia, úsese la documentación puesta a disposición en el área de distribuidores.
Publicado el febrero 25, 2009 en Desarrolladores, Distribuidores, Implantaciones y etiquetado en .net, c#, delphi, dll terceros. Guarda el enlace permanente. Dejar un comentario.
Dejar un comentario