Importante

Para poder utilizar la funcionalidad de firma con tabletas WACOM necesitamos estar en una versión 2400 H64 o superior.


En este artículo vamos a ver como podemos implementar la firma de documentos utilizando una tableta WACOM (Modelo STU-540) en formularios, estándar o personalizados, de una forma similar a la implementación estándar sobre los albaranes de venta.


En este caso vamos a añadir la firma sobre las facturas de venta almacenando los datos de firma (Firma y datos biométricos) sobre los campos configurables 'Pers_FirmaB64' y 'Pers_FirmaBiometria' en al tabla 'Conf_Facturas_Cli'


NOTA: Actualmente no es posible crear directamente desde el ERP el tipo de campo necesario para almacenar un campo en base64 y su firma biométrica que es Varchar(MAX) por lo que tendrá que crearlos mediante el administrador SQL Server.


Código en VB6:

Sub Initialize()
    'Añadir un botón personalizado para la firma
     gform.Botonera.ActivarScripts = True 
     gform.Botonera.BotonAdd "Pers Firmar", "btnPERS_Firmar", , 0, True, 123
     gForm.Botonera.HabilitaBotones
End Sub

Sub Botonera_AfterExecute(aBotonera, aBoton)
  If aBoton.Name = "btnPERS_Firmar" Then  
    FirmarDocumento
  End If
End Sub

Sub FirmarDocumento
  Dim lPad 'As Object
  Dim lRes 'As boolean
  Dim lError 'As string
  Dim lFirmaB64 'As String
  Dim lFirmaBio 'As string
  
  'Llamada al Ahora_Proceso
  Set lPad = gCn.AhoraProceso("ObjFirmaDocumentosEPad", False)
  With lPad
    'Establecer el aspecto de la ventana de firma
    .TextoVentana = "Firmar factura" 'Título de la ventana
    .TextoDocumento = "Factura nº " & gForm.Controls("NumFactCliente").Text & " de " & gForm.Controls("Cliente").Text & " (" & gForm.Controls("FechaFact").Text & ")" 'Texto sobre el objeto
    
    lRes = .ObtenerFirma(lError)  'Muestra la pantalla hasta que el usuario del ERP o el firmante pulsen el botón de "Aceptar" o "Cancelar"   
    If lRes Then
      If lError = "" Then 'Firma correcta: guardar el gráfico y sus datos biométricos
        lFirmaB64 = .FirmaBase64(lError)
        lFirmaBio = .ObtenerBiometriaFirma
        
        If lFirmaB64 = "" Then
          MsgBox lError, vbCritical, "Firma"
        Else
          'Guardar la firma en el pedido en nuestro campo configurable. ¡¡ LOS CAMPOS TIENEN QUE SER VARCHAR(MAX) !!
          If Not gCn.ExecuteSql("UPDATE Conf_Facturas_Cli Set Pers_FirmaB64 = '" & CStr(lFirmaB64) & "', Pers_FirmaBiometria = '" & CStr(lFirmaBio) & "' WHERE idFactura = " & gForm.Controls("EObjeto").ObjGlobal.Propiedades("IdFactura")) Then                                                        
            MsgBox "Error al guardar la firma en la factura.", vbCritical, "Firma"
          Else
            MsgBox "La factura se ha firmado correctamente.", vbInformation, "Firma"
          End If
        End If
      Else
        MsgBox lError, vbExclamation, "Firma"     ' Han cancelado la firma
      End If
    Else
      MsgBox lError, vbCritical, "Firma"    ' Error: ePad no conectado, por ejemplo.
    End If    
  End With
  Set lPad = Nothing
End Sub



Código en C#:

using AhoraCore;
using AhoraDispositivos;
using AhoraOCX;
using AhoraSistema;
using static AhoraCore.VBA.Interaction;
using static AhoraCore.VBA.Conversion;

namespace AhoraScriptsPantalla
{
  public class AhoraCl_frmFacturas : AhoraOCX.AhoraBaseScript
  {

    public void Initialize()
    {
      (gForm.Controls["Botonera"] as ICntBotonera).ActivarScripts = true;
      (gForm.Controls["Botonera"] as ICntBotonera).BotonAdd("Pers Firmar", "btnPERS_Firmar", "", 0, true, 123);
      (gForm.Controls["Botonera"] as ICntBotonera).HabilitaBotones();
        }

    public void Botonera_AfterExecute(ICntBotonera aBotonera, IAhoraTool aBoton)
    {
      if (aBoton.Name == "btnPERS_Firmar")
      {
        FirmarDocumento();
      }
    }

    public void FirmarDocumento()
    {

      string lFirmaB64 = "";
      string lFirmaBio = "";

            IWacom_Firmar lPad = AhoraCore.AhoraServiceLocator.Current.GetService<AhoraDispositivos.IWacom_Firmar>();
            lPad = (IWacom_Firmar)gCn.AhoraProceso("ObjFirmaDocumentosEPad", out _);
      lPad.TextoVentana = "Firmar factura"; //Título de la ventana"
      lPad.TextoDocumento = "Factura nº " + (gForm.Controls["NumFactCliente"] as ITextoUsuario).Text + " de " + (gForm.Controls["Cliente"] as ITextoUsuario).Text + " (" + (gForm.Controls["FechaFact"] as ITextoUsuario).Text + ")"; //Texto sobre el objeto

      string lError = "";
      bool lRes = lPad.ObtenerFirma(ref lError);
            if (lRes)
            {
                if (lError == "")
                {
                    lFirmaB64 = lPad.FirmaBase64(ref lError);
                    lFirmaBio = lPad.ObtenerBiometriaFirma;

                    if (lFirmaB64 == "")
                    {
                        MsgBox(lError, VbMsgBoxStyle.vbCritical, "Firma");
                    }
                    else
                    {
                        if (!gCn.ExecuteSql("UPDATE Conf_Facturas_Cli Set Pers_FirmaB64 = '" + CStr(lFirmaB64) + "', Pers_FirmaBiometria = '" + CStr(lFirmaBio) + "' WHERE idFactura = " + (gForm.Controls["EObjeto"] as EnlaceObjetos).ObjGlobal["IdFactura"]))
                        {
                            MsgBox("Error al guardar la firma en la factura.", VbMsgBoxStyle.vbCritical, "Firma");
                        }
                        else
                        {
                            MsgBox("La factura se ha firmado correctamente.", VbMsgBoxStyle.vbInformation, "Firma");
                        }
                    }
                }
                else
                {
                    MsgBox(lError, VbMsgBoxStyle.vbExclamation, "Firma"); // Han cancelado la firma
                }
            }
            else
            {
                MsgBox(lError, VbMsgBoxStyle.vbCritical, "Firma"); // Error: ePad no conectado, por ejemplo.
            }
            lPad = null;
        }
  }
}






Campos configurables


Una vez tenemos la firma almacenada en la base de datos, podemos crear una stored similar a la siguiente para poder visualizar la firmas guardadas en un informe de crystal reports:


CREATE PROCEDURE [dbo].[Pers_FirmaFactura_rpt] 
    @idFactura T_Id_Factura 
AS

    SELECT 
        dbo.fun_B64ToImage(Pers_FirmaB64) Firma
    FROM Conf_Facturas_Cli
    WHERE IdFactura=@idFactura

GO
ZPERMISOS Pers_FirmaFactura_rpt


De esta forma poder añadir un subinforme en el report vinculado, en este caso por el idFactura, que muestre por pantalla el resultado de la stored.