FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Digitally sign files (eInvoice xml, pdfs, etc)
Posts: 838
Joined: Fri Feb 10, 2006 12:14 PM
Digitally sign files (eInvoice xml, pdfs, etc)
Posted: Fri Jan 23, 2009 10:55 AM

Can anyone share work experience on this subject (tools used, etc) ?

I need to digitally sign eInvoices with signature and timestamp.
The files can be pdf or xml eInvoice format.

Antonio

Regards

Antonio H Ferreira
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Digitally sign files (eInvoice xml, pdfs, etc)
Posted: Fri Jan 23, 2009 08:38 PM

I am interested in this topic also.

Regards,
James

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: Digitally sign files (eInvoice xml, pdfs, etc)
Posted: Thu Feb 19, 2009 04:10 PM
Sorry about the late post.

ePad.id from Interlink electronics has a few different devices that can capture a customer signature. These devices can be managed from xharbor via ocx controls. The final signature can be imported/exported using blobImport() and BloblExport() as a .jpg into a <binary> field on a .adt file or into a <memo> field on a .dbf and thus, saved.

I'm in the midst of acquiring a new epad id, so I stop development; but below is my initial code that was working with my old ePad.Id. You'll find code using fw's Tactive class as well as using native xharbour activex object creator. It was part of my testing. I hope to return to this project soon.

I believe that once we can acquire signature data, then it is only a matter of placing it on a <form-field> PDF.

Code (fw): Select all Collapse
/* if signing a pdf then, it is assumed that the signature class is the name of the 
pdf without the pdf extension.  If there is no path declaration in the class definition 
then the pdf document must exist on the same path where the system ini file is stored.
*/

#include "fivewin.ch"

//------------------------------------------------------------------------//

CLASS TePad

    DATA oActiveX
    DATA oSearch
    DATA oWnd
    
    DATA cCaption AS CHARACTER INIT "Capture Signature"
    DATA cDispName AS CHARACTER INIT "Not Set"
    DATA cDevice
    DATA cPdf
    
    DATA hDLL
    
    DATA aGetFlds AS ARRAY INIT { "mrecno", ;
                    "dt_stamp", ;
                    "class", ;
                    "sign_data", ;
                    "operator" }
   
    METHOD New()
    METHOD SetProp()
    METHOD PickUpSignature()
    METHOD End()

    METHOD SaveToJpg()
    METHOD GetSigData()

ENDCLASS

//------------------------------------------------------------------------//

METHOD New( oOwner, oProcess ) CLASS TePad
local lOk   := .t.
local oErr
local cEvents   := ""
    
TRY

    ::oActiveX := GETACTIVEOBJECT( "esW25COM.esCapture.1" )

CATCH

    TRY
        ::oActiveX := CREATEOBJECT( "esW25COM.esCapture.1" )
    CATCH
        Alert( "ERROR! SigningPad not avialable. [" + Ole2TxtError()+ "]" )
        ::end()
        Return Nil
    END
END

//  ::oActiveX := TActiveX():New( , "esW25COM.esCapture.1" )
//  ::cDevice := ::oActiveX:GetProp( "ConnectedDevice" ) 
//  ::oClient := ::oActiveX
//  ::oActiveX:bOnEvent := { |e, a| logfile( "trace.log", {EventInfo( e, a ) } ) }
/*----------------------------------------------------------------------------
ConnectedDevice = 
{98C174D3-6D2A-4509-96DB-D5B34FA7A561}: Interlink ePadInk
{7FCD9512-8763-436E-8747-40972EE28EFD}: Interlink ePad
{C55C5D54-8A92-48AD-A32F-1FC58092A581}: Interlink ePadID 
------------------------------------------------------------------------------

CATCH oErr

    ::end()
    Return Nil
    
END*/
/*  ::bInit := { |o| o:hide() } 
    ::bValid := { || .f. }
    ::Activate() */
    
RETURN Self 

//------------------------------------------------------------------------//
METHOD SetProp() CLASS TePad

    ::oActiveX:SetProp( "SignDlgCaption", ::cCaption )
    ::oActiveX:SetProp( "DisplayName", ::cDispName )
    ::oActiveX:SetProp( "ShowSignerName", 1 )  //true
    ::oActiveX:SetProp( "EnableAntiAliasing", 1 ) 

RETURN NIL

//------------------------------------------------------------------------//
METHOD PickUpSignature() CLASS TePad
local nRet 

TRY
    ::oActiveX:Do( "ClearSign" )
    ::oActiveX:Do( "StartSign" , 0, 1 ) 
    
CATCH
    logfile( "trace.log", {"catched with errors"})
END

Logfile( "trace.log", { "Just testing", ::cDevice } )

Return nRet

//------------------------------------------------------------------------//
METHOD End() CLASS TePad
logfile( "trace.log", {"ending TePad" } )
    if ::oActiveX <> Nil .and. ValType( ::oActiveX ) ==     "O"
//      ::oActiveX:Do( "CloseConnection" )
    endif

    iif( ::hDLL <> NIL, FreeLibrary( ::hDLL ), )
    
    DeleteObject( ::oSearch )
    DeleteObject( ::oActiveX )
    DeleteObject( ::oWnd )
    DeleteObject( Self )
    
RETURN Nil

//------------------------------------------------------------------------//
METHOD SaveToJpg() CLASS TePad
local cFile     := Temp_Name( "jpg" )

//  ::oActiveX:Do( "SaveToFile", cFile, nheight, nwidth, 1 )
    
Return Nil

//------------------------------------------------------------------------//
METHOD GetSigData() CLASS TePad

/*Private Function GenerateSignImage() As Boolean
    Dim strSignData As String
    strSignData = esCapture1.GetSignData
    If strSignData <> vbNullString Then
        strSignImgData = esCapture1.GetImageData(167, 87, cmbImageType1.ListIndex, 0)
        'get the signature data from the database and display it on the picture box
        esCapture1.GenerateImageFromBase64 strSignImgData, strSigImgPath
        Set picSign.Picture = LoadPicture(strSigImgPath)
        If Trim(txtFolderName.Text) <> vbNullString Then
            Select Case cmbImageType1.ListIndex
                Case 0:
                    FileCopy strSigImgPath, txtFolderName.Text & "\" & txtSignerName.Text & "Signature.bmp"
                Case 1:
                    FileCopy strSigImgPath, txtFolderName.Text & "\" & txtSignerName.Text & "Signature.jpg"
                Case 2:
                    FileCopy strSigImgPath, txtFolderName.Text & "\" & txtSignerName.Text & "Signature.gif"
            End Select
        End If
        GenerateSignImage = True
    End If
    esCapture1.CloseConnection
End Function

*/
Return Nil

//------------------------------------------------------------------------//
static function EventInfo( e, a )
local cMsg  := "Event:" + cValToChar( e ) + CRLF
local n 

    cMsg += "Parms:"
    for n:=1 to Len ( a ) 
        cMsg += cValToChar( a[n] ) + CRLF
    next n
    
return cMsg + CRLF
//------------------------------------------------------------------------//

Continue the discussion