Classe para NFe alguem tem interesse?

Projeto hbNFe (Nota Fiscal Eletronica/Danfe) para [x]Harbour

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Classe para NFe alguem tem interesse?

Mensagem por JoséQuintas »

Aqui fiz apenas um teste, não quer dizer que seja válido, apenas passou na compilação/linquedição.
Isso facilitaria danfe, geração de XML e tudo mais.
Mas não encontrei ainda um fonte simples que esclareça como usar
A idéia é ter uma variável com os dados da nota, no estilo do xml.
Posteriormente, essa classe poderia ter os métodos pra leitura de xml, geração de xml ou geração de danfe, a partir dos dados.
Mas com a variável criada, as funções de leitura/geração xml/danfe poderiam ser até em módulos separados, apenas usando a variável/classe da nota fiscal.

Código: Selecionar todos

Procedure Teste
// Compilou, mas é apenas um teste teórico, não válido

NotaFiscal:Chave := "351109xxxxxxx"
NotaFiscal:Emitente:Nome := "TESTE"

#include "hbclass.ch"

CLASS Emitente FROM NotaFiscal
   DATA Nome INIT ""
   DATA Endereco INIT ""
   DATA Cidade INIT ""
   DATA UF INIT ""
EndClass
   
CLASS Destinatario From NotaFiscal
   DATA Nome INIT ""
   DATA Endereco INIT ""
   DATA Cidade INIT ""
   DATA UF INIT ""
EndClass
   
CLASS NotaFiscal
   DATA Chave INIT ""
   // METHOD Emitente
   // METHOD Destinatario
EndClass
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Classe para NFe alguem tem interesse?

Mensagem por JoséQuintas »

Obs. Fiquei na dúvida sobre postar aqui ou no Harbour, mas a classe em questão pode facilitar o projeto

Ainda apenas teórico, mas funcionou, faltava indicar o Self: (que pode ser abreviado com ::)

Código: Selecionar todos


NotaFiscal := TypeNotaFiscal():New()
NotaFiscal:Chave = "xxxxx"
NotaFiscal:Emitente:Nome = "TESTE"
? "Chave:" + NotaFiscal:Chave
? "Emitente:" + NotaFiscal:Emitente:Nome


#include "hbclass.ch"

CREATE CLASS TypeEmitente from TypeNotaFiscal
   METHOD New() CONSTRUCTOR
   DATA Nome INIT "" EXPORTED
   DATA Endereco as string
   DATA Cidade as string
   DATA UF as string
EndClass

Method New() Class TypeEmitente
   Self:Nome := Self:Endereco := Self:Cidade := Self:UF := ""
Return SELF

Create Class TypeDestinatario From TypeNotaFiscal
   DATA Nome as string
   DATA Endereco as string
   DATA Cidade as string
   DATA UF as string
   Method New() constructor
EndClass

Method New() Class TypeDestinatario
   Self:Nome := Self:Endereco := Self:Cidade := Self:UF := ""
Return SELF
   
Create Class TypeNotaFiscal
   DATA Chave INIT "" EXPORTED
   DATA Emitente EXPORTED
   DATA Destinatario  EXPORTED
   Method New() constructor
EndClass

Method New() Class TypeNotaFiscal
   Self:Chave := ""
   Self:Emitente := TypeEmitente():New()
   Self:Destinatario := TypeDestinatario():New()
Return SELF

José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

quintas
o chato é mapear tudo
o mais trabalhoso são os ambientes dos itens
vc vai ter que fazer tipo um nfe:additem(), onde devera criar uma classe on the fly ex, controlando por um n ou array os itens
nfe:item(1):cCodigo := '123'

estou trabalhando em cima da assinatura usando openssl que esta sendo um tanto trabalhoso, acredito que terei que usar o xmlsec tb, isso tudo por command line, imagina só a quantidade de exemplos, quase nada, rs

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Classe para NFe alguem tem interesse?

Mensagem por JoséQuintas »

Achei isto nas minhas "anotações", pra assinar direto usando API, veja se ajuda.

Código: Selecionar todos

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior = 0   'vbNone
  MTSTransactionMode = 0   'NotAnMTSObject
End
Option Explicit


'=============================================================================================================
'
' cCrypt Class Module
' -------------------
'
' Created By  : Kevin Wilson
'               http://www.TheVBZone.com   ( The VB Zone )
'               http://www.TheVBZone.net   ( The VB Zone .net )
'
' Created On  : May 01, 2001
' Last Update : January 23, 2007
'
' VB Versions : 6.0
'
' Requires    : Windows 95 OSR2 or later (or Windows 95 with Internet Explorer 3.02 or later)
'
' Description : This class module was created to easily encrypt and decrypt strings using Hash encryption
'               via the Windows API.
'
'=============================================================================================================
'
' LEGAL:
'
' You are free to use this code as long as you keep the above heading information intact and unchanged. Credit
' given where credit is due.  Also, it is not required, but it would be appreciated if you would mention
' somewhere in your compiled program that that your program makes use of code written and distributed by
' Kevin Wilson (www.TheVBZone.com).  Feel free to link to this code via your web site or articles.
'
' You may NOT take this code and pass it off as your own.  You may NOT distribute this code on your own server
' or web site.  You may NOT take code created by Kevin Wilson (www.TheVBZone.com) and use it to create products,
' utilities, or applications that directly compete with products, utilities, and applications created by Kevin
' Wilson, TheVBZone.com, or Wilson Media.  You may NOT take this code and sell it for profit without first
' obtaining the written consent of the author Kevin Wilson.
'
' These conditions are subject to change at the discretion of the owner Kevin Wilson at any time without
' warning or notice.  Copyright© by Kevin Wilson.  All rights reserved.
'
'=============================================================================================================


Public Enum EncryptReturnType
   ert_String = 0
   ert_HEX = 1
   ert_Numeric = 3
End Enum

' Constants - CryptAcquireContext.dwProvType
Private Const PROV_RSA_FULL = 1        ' The PROV_RSA_FULL provider type supports both digital signatures and data encryption. It is considered a general purpose CSP. The RSA public-key algorithm is used for all public-key operations.
Private Const PROV_RSA_SIG = 2         ' The PROV_RSA_SIG provider type is a subset of PROV_RSA_FULL. It supports only those functions and algorithms required for hashes and digital signatures.
Private Const PROV_RSA_SCHANNEL = 12   ' The PROV_RSA_SCHANNEL provider type supports both RSA and Schannel protocols.
Private Const PROV_DSS = 3             ' The PROV_DSS provider type, like PROV_RSA_SIG, only supports hashes and digital signatures. The signature algorithm specified by the PROV_DSS provider type is the Digital Signature Algorithm (DSA).
Private Const PROV_DSS_DH = 13         ' The PROV_DSS_DH provider is a superset of the PROV_DSS provider type.
Private Const PROV_DH_SCHANNEL = 18    ' The PROV_DH_SCHANNEL provider type supports both Diffie-Hellman and Schannel protocols
Private Const PROV_FORTEZZA = 4        ' The PROV_FORTEZZA provider type contains a set of cryptographic protocols and algorithms owned by the National Institute of Standards and Technology (NIST).
Private Const PROV_MS_EXCHANGE = 5     ' The PROV_MS_EXCHANGE provider type is designed for the cryptographic needs of the Microsoft Exchange mail application and other applications compatible with Microsoft Mail. This provider type is preliminary.
Private Const PROV_SSL = 6             ' The PROV_SSL provider type supports the Secure Sockets Layer (SSL) protocol.

' Constants - CryptAcquireContext.pszProvider
' (The following Cryptographic Service Provider (CSP) names are defined in the Win32 API)
Private Const MS_DEF_PROV              As String = "Microsoft Base Cryptographic Provider v1.0" & vbNullChar
Private Const MS_ENHANCED_PROV         As String = "Microsoft Enhanced Cryptographic Provider" & vbNullChar
Private Const MS_STRONG_PROV           As String = "Microsoft Strong Cryptographic Provider" & vbNullChar
Private Const MS_DEF_RSA_SIG_PROV      As String = "Microsoft RSA Signature Cryptographic Provider" & vbNullChar
Private Const MS_DEF_RSA_SCHANNEL_PROV As String = "Microsoft RSA SChannel Cryptographic Provider" & vbNullChar
Private Const MS_DEF_DSS_PROV          As String = "Microsoft Base DSS Cryptographic Provider" & vbNullChar
Private Const MS_DEF_DSS_DH_PROV       As String = "Microsoft Base DSS and Diffie-Hellman Cryptographic Provider" & vbNullChar
Private Const MS_ENH_DSS_DH_PROV       As String = "Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider" & vbNullChar
Private Const MS_DEF_DH_SCHANNEL_PROV  As String = "Microsoft DH SChannel Cryptographic Provider" & vbNullChar
Private Const MS_SCARD_PROV            As String = "Microsoft Base Smart Card Cryptographic Provider" & vbNullChar

' Algorithm Classes
Private Const ALG_CLASS_ANY = 0
Private Const ALG_CLASS_SIGNATURE = 8192     '(1 << 13)
Private Const ALG_CLASS_MSG_ENCRYPT = 16384  '(2 << 13)
Private Const ALG_CLASS_DATA_ENCRYPT = 24576 '(3 << 13)
Private Const ALG_CLASS_HASH = 32768         '(4 << 13)
Private Const ALG_CLASS_KEY_EXCHANGE = 40960 '(5 << 13)
Private Const ALG_CLASS_ALL = 57344          '(7 << 13)

' Algorithm Types
Private Const ALG_TYPE_ANY = 0
Private Const ALG_TYPE_DSS = 512            '(1 << 9)
Private Const ALG_TYPE_RSA = 1024           '(2 << 9)
Private Const ALG_TYPE_BLOCK = 1536         '(3 << 9)
Private Const ALG_TYPE_STREAM = 2048        '(4 << 9)
Private Const ALG_TYPE_DH = 2560            '(5 << 9)
Private Const ALG_TYPE_SECURECHANNEL = 3072 '(6 << 9)

' Sub-IDs (Windows Compatible)
Private Const ALG_SID_ANY = 0
Private Const ALG_SID_MD2 = 1
Private Const ALG_SID_RC2 = 2
Private Const ALG_SID_MD5 = 3
Private Const ALG_SID_SHA = 4
Private Const ALG_SID_SHA1 = 4
Private Const ALG_SID_MAC = 5
Private Const ALG_SID_SSL3SHAMD5 = 8
Private Const ALG_SID_HMAC = 9

' Stream Cipher Sub-IDs
Private Const ALG_SID_RC4 = 1
Private Const ALG_SID_SEAL = 2

' Constants - CryptAcquireContext.dwFlags
Private Const CRYPT_VERIFYCONTEXT = &HF0000000 ' The application has no access to the private keys, and the pszContainer parameter must be set to NULL.  This option is intended for applications that do not use private keys.  When CryptAcquireContext is called, many CSPs require input from the owning user before granting access to the private keys in the key container. For example, the private keys can be encrypted, requiring a password from the user before they can be used. However, if the CRYPT_VERIFYCONTEXT flag is specified, access to the private keys is not required and the user interface can be bypassed.
Private Const CRYPT_NEWKEYSET = &H8            ' A new key container is created with the name specified by pszContainer. If pszContainer is NULL, a key container with the default name is created.
Private Const CRYPT_MACHINE_KEYSET = &H20      ' By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored in the user's profile. The CRYPT_MACHINE_KEYSET flag can be combined with all of the other flags to indicate that the key container of interest is a machine key container and the CSP treats it as such. For Base Providers, this means that the keys are stored locally on the computer that created the key container. If a key container is to be a machine container, the CRYPT_MACHINE_KEYSET flag must be used with all calls to CryptAcquireContext that reference the machine container. The CRYPT_MACHINE_KEYSET flag is useful when the user is accessing from a service or user account that did not log on interactively When key containers are created, most CSPs do not automatically create any public/private key pairs. These keys must be created as a separate step with the CryptGenKey function.
Private Const CRYPT_DELETEKEYSET = &H10        ' The key container specified by pszContainer is deleted. If pszContainer is NULL, the key container with the default name is deleted. All key pairs in the key container are also destroyed.  When this flag is set, the value returned in phProv is undefined, and thus, the CryptReleaseContext function need not be called afterwards.
Private Const CRYPT_SILENT = &H40              ' The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error. In addition, if calls are made to CryptGenKey with the CRYPT_USER_PROTECTED flag with a context that has been acquired with the CRYPT_SILENT flag, the calls fail and the CSP sets NTE_SILENT_CONTEXT.  CRYPT_SILENT is intended for use with applications for which the UI cannot be displayed by the CSP.  This flag is supported with Microsoft® Windows® 2000 or later. It is not supported in Windows 98 or Microsoft® Internet Explorer version 5.0.

' Constants - CryptHashData.dwFlags
Private Const CRYPT_USERDATA = 1 'All Microsoft Cryptographic Providers ignore this parameter. For any CSP that does not ignore this parameter, if this flag is set, the CSP prompts the user to input data directly. This data is added to the hash. The application is not allowed access to the data. This flag can be used to allow the user to enter a PIN into the system.

' Constants - CryptDeriveKey.Algid
Private Const CALG_RC2 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_RC2) ' RC2 block cipher
Private Const CALG_RC4 = (ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_STREAM Or ALG_SID_RC4) 'RC4 stream cipher

' Constants - CryptDecrypt.dwFlags
Private Const CRYPT_OAEP = &H40 ' When set with the MS Enhanced Provider and RSA encryption/decryption causes PKCS #1 version 2 formatting to be used.

' Constants - CryptCreateHash.Algid
Private Const CALG_HMAC = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_HMAC)              ' HMAC, a keyed hash algorithm
Private Const CALG_MAC = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MAC)                ' MAC Message Authentication Code
Private Const CALG_MD2 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD2)                ' MD2 hashing algorithm
Private Const CALG_MD5 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5)                ' MD5 hashing algorithm
Private Const CALG_SHA = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA)                ' US DSA Secure Hash Algorithm
Private Const CALG_SHA1 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA1)              ' Same as CALG_SHA
Private Const CALG_SSL3_SHAMD5 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SSL3SHAMD5) ' SSL3 client authentication

' Error Constants
Private Const ERROR_INVALID_HANDLE = 6&            ' One of the parameters specifies an invalid handle.
Private Const ERROR_INVALID_PARAMETER = 87         ' One of the parameters contains an invalid value. This is most often an illegal pointer.
Private Const ERROR_NOT_ENOUGH_MEMORY = 8          ' The operating system ran out of memory during the operation.
Private Const ERROR_BUSY = 170&                    ' The hash object specified by hHash is currently being used by another process.
Private Const NTE_BAD_ALGID = &H80090008           ' The Algid parameter specifies an algorithm that this CSP does not support.
Private Const NTE_BAD_DATA = &H80090005            ' The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size.
Private Const NTE_BAD_FLAGS = &H80090009           ' The dwFlags parameter has an illegal value.
Private Const NTE_BAD_HASH = &H80090002            ' The hash object specified by the hHash parameter is invalid.
Private Const NTE_BAD_HASH_STATE = &H8009000C      ' An attempt was made to add data to a hash object that is already marked "finished".
Private Const NTE_BAD_KEY = &H80090003             ' A keyed hash algorithm (such as CALG_MAC) is specified by Algid and the hKey parameter is either zero or it specifies an invalid key handle. This error code will also be returned if the key is to a stream cipher, or if the cipher mode is anything other than CBC.
Private Const NTE_BAD_KEYSET = &H80090016          ' The Registry entry for the key container could not be opened and may not exist.
Private Const NTE_BAD_KEYSET_PARAM = &H8009001F    ' The pszContainer or pszProvider parameter is set to an illegal value.
Private Const NTE_BAD_LEN = &H80090004             ' The CRYPT_USERDATA flag is set and the dwDataLen parameter has a nonzero value.
Private Const NTE_BAD_PROV_TYPE = &H80090014       ' The value of the dwProvType parameter is out of range. All provider types must be from 1 to 999, inclusive.
Private Const NTE_BAD_SIGNATURE = &H80090006       ' The provider DLL signature did not verify correctly. Either the DLL or the digital signature has been tampered with.
Private Const NTE_BAD_UID = &H80090001             ' The CSP context that was specified when the hash object was created cannot be found.
Private Const NTE_DOUBLE_ENCRYPT = &H80090012      ' The application attempted to encrypt the same data twice.
Private Const NTE_EXISTS = &H8009000F              ' The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists.
Private Const NTE_FAIL = &H80090020                ' The function failed in some unexpected way.
Private Const NTE_KEYSET_ENTRY_BAD = &H8009001A    ' The Registry entry for the pszContainer key container was found (in the HKEY_CURRENT_USER window), but is corrupt. See the section System Administration for details about CryptoAPI’s Registry usage.
Private Const NTE_KEYSET_NOT_DEF = &H80090019      ' No Registry entry exists in the HKEY_CURRENT_USER window for the key container specified by pszContainer.
Private Const NTE_NO_MEMORY = &H8009000E           ' The CSP ran out of memory during the operation.
Private Const NTE_PROV_DLL_NOT_FOUND = &H8009001E  ' The provider DLL file does not exist or is not on the current path.
Private Const NTE_PROV_TYPE_ENTRY_BAD = &H80090018 ' The Registry entry for the provider type specified by dwProvType is corrupt. This error may relate to either the user default CSP list or the machine default CSP list. See the section System Administration for details about CryptoAPI’s Registry usage.
Private Const NTE_PROV_TYPE_NO_MATCH = &H8009001B  ' The provider type specified by dwProvType does not match the provider type found in the Registry. Note that this error can only occur when pszProvider specifies an actual CSP name.
Private Const NTE_PROV_TYPE_NOT_DEF = &H80090017   ' No Registry entry exists for the provider type specified by dwProvType.
Private Const NTE_PROVIDER_DLL_FAIL = &H8009001D   ' The provider DLL file could not be loaded, and may not exist. If it exists, then the file is not a valid DLL.
Private Const NTE_SIGNATURE_FILE_BAD = &H8009001C  ' An error occurred while loading the DLL file image, prior to verifying its signature.

' Property Variables
Private p_Password   As String
Private p_CSP_String As String
Private p_CSP_Type   As Long

' Win32 API Declarations - General
Private Declare Function GetLastError Lib "KERNEL32" () As Long

' Win32 API Declarations - Encryption
Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" (ByRef phProv As Long, ByVal pszContainer As Long, ByVal pszProvider As String, ByVal dwProvType As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptCreateHash Lib "advapi32.dll" (ByVal hProv As Long, ByVal Algid As Long, ByVal hKey As Long, ByVal dwFlags As Long, ByRef phHash As Long) As Long
Private Declare Function CryptHashData Lib "advapi32.dll" (ByVal hHash As Long, ByVal pbData As String, ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptDeriveKey Lib "advapi32.dll" (ByVal hProv As Long, ByVal Algid As Long, ByVal hBaseData As Long, ByVal dwFlags As Long, ByRef phKey As Long) As Long
Private Declare Function CryptDestroyHash Lib "advapi32.dll" (ByVal hHash As Long) As Long
Private Declare Function CryptDestroyKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function CryptEncrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, ByRef pdwDataLen As Long, ByVal dwBufLen As Long) As Long
Private Declare Function CryptDecrypt Lib "advapi32.dll" (ByVal hKey As Long, ByVal hHash As Long, ByVal Final As Long, ByVal dwFlags As Long, ByVal pbData As String, ByRef pdwDataLen As Long) As Long
Private Declare Function CryptReleaseContext Lib "advapi32.dll" (ByVal hProv As Long, ByVal dwFlags As Long) As Long


'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Private Sub Class_Initialize()
  p_Password = "password"
  p_CSP_String = MS_STRONG_PROV   'MS_DEF_PROV
  p_CSP_Type = PROV_RSA_FULL
End Sub


'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Public Property Get Password() As String
  Password = p_Password
End Property
Public Property Let Password(ByVal NewValue As String)
  p_Password = NewValue
End Property


'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


' This procedure is the one that actually does the work of decrypting the data
Public Function Decrypt_String(ByVal StringToDecrypt As String, _
                               ByRef Return_String As String, _
                               Optional ByVal ConvertFromFormat As EncryptReturnType = ert_HEX, _
                               Optional ByRef Return_ErrNum As Long = 0, _
                               Optional ByRef Return_ErrDesc As String = "") As Boolean
On Error GoTo ErrorTrap
   
   Dim lngHash         As Long
   Dim lngKey          As Long
   Dim lngCryptProv    As Long
   Dim strCryptBuffer  As String
   Dim lngCryptBuffLen As Long
   
   ' Set default values
   Return_String = ""
   Return_ErrNum = 0
   Return_ErrDesc = ""
   
   ' Make sure the user has specified a password
   If p_Password = "" Then
      Return_ErrNum = -1: Return_ErrDesc = "No password has been defined to decrypt with"
      Exit Function
      
   ' Make sure decrypt string is valid
   ElseIf StringToDecrypt = "" Then
      Return_ErrNum = -1: Return_ErrDesc = "No string specified to decrypt"
      Exit Function
      
   ' Make sure the convertion type is vaild
   ElseIf ConvertFromFormat <> ert_String And ConvertFromFormat <> ert_Numeric And ConvertFromFormat <> ert_HEX Then
      Return_ErrNum = -1: Return_ErrDesc = "Convert type is invalid"
      Exit Function
   End If
   
   Select Case ConvertFromFormat
      
      Case ert_Numeric
         
         ' Strip out any "white space" characters"
         StringToDecrypt = Replace(StringToDecrypt, " ", "")
         StringToDecrypt = Replace(StringToDecrypt, vbTab, "")
         StringToDecrypt = Replace(StringToDecrypt, vbCr, "")
         StringToDecrypt = Replace(StringToDecrypt, vbLf, "")
         
         ' If the user is converting from a number, it has to be numeric
         If ContainsNonNumeric(StringToDecrypt) = True Then
            Return_ErrNum = -1: Return_ErrDesc = "Invalid decimal string specified to convert.  Conversion string must only contain numeric characters."
            Exit Function
         End If
         
         ' Convert the numbers to string
         StringToDecrypt = Convert_NUMtoSTR(StringToDecrypt)
         
      Case ert_HEX
         
         ' Strip out any "white space" characters"
         StringToDecrypt = Replace(StringToDecrypt, " ", "")
         StringToDecrypt = Replace(StringToDecrypt, vbTab, "")
         StringToDecrypt = Replace(StringToDecrypt, vbCr, "")
         StringToDecrypt = Replace(StringToDecrypt, vbLf, "")
         
         ' Convert the HEX to string
         StringToDecrypt = Convert_HEXtoSTR(StringToDecrypt)
         
   End Select
   
   ' Get handle to the default CSP
   If CryptAcquireContext(lngCryptProv, 0, p_CSP_String, p_CSP_Type, CRYPT_MACHINE_KEYSET) = 0 Then
      ' Bad provider name or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptAcquireContext", False
      Exit Function
   End If
   
   ' Create a hash object
   If CryptCreateHash(lngCryptProv, CALG_MD5, 0, 0, lngHash) = 0 Then
      ' Error creating encrypt object or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptCreateHash", False
      GoTo CleanUp
   End If
   
   ' Hash in the password text
   If CryptHashData(lngHash, p_Password, Len(p_Password), 0) = 0 Then
      ' Error passing key or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptHashData", False
      GoTo CleanUp
   End If
   
   ' Create a session key from the hash object
   If CryptDeriveKey(lngCryptProv, CALG_RC4, lngHash, 0, lngKey) = 0 Then
      ' Error creating a session key or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptDeriveKey", False
      GoTo CleanUp
   End If
   
   ' Destroy the hash object.
   CryptDestroyHash lngHash
   lngHash = 0
   
   ' Prepare strCryptBuffer for CryptDecrypt
   lngCryptBuffLen = Len(StringToDecrypt) * 2
   strCryptBuffer = String(lngCryptBuffLen, vbNullChar)
   'LSet strCryptBuffer = StringToDecrypt
   Mid(strCryptBuffer, 1) = StringToDecrypt
   
   ' Decrypt data
   If CryptDecrypt(lngKey, 0, 1, 0, strCryptBuffer, lngCryptBuffLen) = 0 Then
      If CheckGetLastError(GetLastError, , , "CryptDecrypt", True) = False Then Err.Raise -1, "CryptDecrypt", "Error decrypting string or API error"
      GoTo CleanUp
   End If
   
   ' Setup output buffer with just decrypted data
   Return_String = Mid(strCryptBuffer, 1, lngCryptBuffLen / 2)
   
   ' Success!
   Decrypt_String = True
   
CleanUp:
   
   ' Destroy session key
   If lngKey <> 0 Then CryptDestroyKey lngKey
   
   ' Destroy hash object
   If lngHash <> 0 Then CryptDestroyHash lngHash
   
   ' Release Context provider handle
   If lngCryptProv <> 0 Then CryptReleaseContext lngCryptProv, 0
   
   Exit Function
   
ErrorTrap:
   
   Return_ErrNum = Err.Number
   Return_ErrDesc = Err.Description
   Err.Clear
   GoTo CleanUp
   
End Function

' This method is the method that actually does the work of encrypting the data
Public Function Encrypt_String(ByVal StringToEncrypt As String, _
                               ByRef Return_String As String, _
                               Optional ByVal ConvertToFormat As EncryptReturnType = ert_HEX, _
                               Optional ByRef Return_ErrNum As Long = 0, _
                               Optional ByRef Return_ErrDesc As String = "") As Boolean
On Error GoTo ErrorTrap
   
   Dim lngHash         As Long
   Dim lngKey          As Long
   Dim lngCryptProv    As Long
   Dim lngCryptLen     As Long
   Dim strCryptBuffer  As String
   Dim lngCryptBuffLen As Long
   
   ' Set default values
   Return_String = ""
   Return_ErrNum = 0
   Return_ErrDesc = ""
   
   ' Make sure the user has specified a password
   If p_Password = "" Then
     Return_ErrNum = -1: Return_ErrDesc = "No password has been defined to encrypt with"
     Exit Function
     
   ' Make sure encrypt string is valid
   ElseIf StringToEncrypt = "" Then
     Return_ErrNum = -1: Return_ErrDesc = "No string specified to encrypt"
     Exit Function
     
   ' Make sure the convertion type is vaild
   ElseIf ConvertToFormat <> ert_String And ConvertToFormat <> ert_Numeric And ConvertToFormat <> ert_HEX Then
      Return_ErrNum = -1: Return_ErrDesc = "Convert type is invalid"
      Exit Function
   End If
   
   ' Get handle to the default CSP
   If CryptAcquireContext(lngCryptProv, 0, p_CSP_String, p_CSP_Type, CRYPT_MACHINE_KEYSET) = 0 Then
      
      ' If there is no default key container then create one using Flags field
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptAcquireContext", False
      If Return_ErrNum = -2146893802 Then
         Return_ErrNum = 0
         Return_ErrDesc = ""
         If CryptAcquireContext(lngCryptProv, 0, p_CSP_String, p_CSP_Type, CRYPT_NEWKEYSET Or CRYPT_MACHINE_KEYSET) = 0 Then
            CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptAcquireContext", False
            Exit Function
         End If
      Else
         Exit Function
      End If
   End If
   
   ' Create a hash object
   If CryptCreateHash(lngCryptProv, CALG_MD5, 0, 0, lngHash) = 0 Then
      ' Error creating encrypt object or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptCreateHash", False
      GoTo CleanUp
   End If
   
   ' Hash in the password text
   If CryptHashData(lngHash, p_Password, Len(p_Password), 0) = 0 Then
      ' Error passing key or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptHashData", False
      GoTo CleanUp
   End If
   
   ' Create a session key from the hash object.
   If CryptDeriveKey(lngCryptProv, CALG_RC4, lngHash, 0, lngKey) = 0 Then
      ' Error creating session key or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptDeriveKey", False
      GoTo CleanUp
   End If
   
   ' Destroy the hash object.
   CryptDestroyHash lngHash
   lngHash = 0
   
   ' Create a buffer for the CryptEncrypt function
   lngCryptLen = Len(StringToEncrypt)
   lngCryptBuffLen = lngCryptLen * 2
   strCryptBuffer = String(lngCryptBuffLen, vbNullChar)
   'LSet strCryptBuffer = StringToEncrypt
   Mid(strCryptBuffer, 1) = StringToEncrypt
   
   ' Encrypt the text data
   If CryptEncrypt(lngKey, 0, 1, 0, strCryptBuffer, lngCryptLen, lngCryptBuffLen) = 0 Then
      ' Error encrypting the data or API error
      CheckGetLastError Err.LastDllError, Return_ErrNum, Return_ErrDesc, "CryptEncrypt", False
      GoTo CleanUp
   End If
   
   ' Return the results
   Return_String = Mid(strCryptBuffer, 1, lngCryptLen)
   Select Case ConvertToFormat
      Case ert_Numeric: Return_String = Convert_STRtoNUM(Return_String)
      Case ert_HEX:     Return_String = Convert_STRtoHEX(Return_String)
   End Select
   
   ' Success!
   Encrypt_String = True
   
CleanUp:
   
   ' Destroy session key.
   If lngKey <> 0 Then CryptDestroyKey lngKey
   
   ' Destroy hash object
   If lngHash <> 0 Then CryptDestroyHash lngHash
   
   ' Release Context provider handle
   If lngCryptProv <> 0 Then CryptReleaseContext lngCryptProv, 0
   
   Exit Function
   
ErrorTrap:
   Return_ErrNum = Err.Number
   Return_ErrDesc = Err.Description
   Err.Clear
   GoTo CleanUp

End Function


'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


' Function that takes a string and takes it letter by letter and converts it
' the ASCII numerical equivelent... and then returns a string of numbers
Private Function Convert_STRtoNUM(ByVal StringToConvert As String) As String
On Error Resume Next
  
   Dim lngCounter As Long
   
   ' Set default values
   Err.Clear
   Convert_STRtoNUM = ""
   
   ' Loop through the string and convert it to character numbers 1 character at a time
   For lngCounter = 1 To Len(StringToConvert)
      Convert_STRtoNUM = Convert_STRtoNUM & Right("00" & CStr(Asc(Mid(StringToConvert, lngCounter, 1))), 3)
   Next
   
End Function

' Function that takes a string and takes it letter by letter and converts it
' the string equivelent... and then returns a string of characters
Private Function Convert_NUMtoSTR(ByVal NumbersToConvert As String, _
                                 Optional ByVal blnContinueOnError As Boolean = True, _
                                 Optional ByRef Return_ErrorOccured As Boolean = False) As String
On Error GoTo ErrorTrap
   
   Dim lngCounter As Long
   
   ' Set default values
   Err.Clear
   Convert_NUMtoSTR = ""
   Return_ErrorOccured = False
   
   ' Make sure the string has the right number of characters (devisible by 3 evenly)
   If Len(NumbersToConvert) Mod 3 <> 0 Then
      Return_ErrorOccured = True
      If blnContinueOnError = False Then Exit Function
   End If
   
   ' Loop through the string 3 characters at a time and convert the character values to string
   For lngCounter = 1 To Len(NumbersToConvert) Step 3
      Convert_NUMtoSTR = Convert_NUMtoSTR & Chr(CLng(Mid(NumbersToConvert, lngCounter, 3)))
   Next
   
   Exit Function
   
ErrorTrap:
   
   Err.Clear
   Return_ErrorOccured = True
   If blnContinueOnError = True Then
      Resume Next
   Else
      Convert_NUMtoSTR = ""
   End If
   
End Function

' Function that takes a string and takes it letter by letter and converts it
' the HEXIDECIMAL equivelent... and then returns a string of HEX values
Private Function Convert_STRtoHEX(ByVal StringToConvert As String) As String
On Error Resume Next
   
   Dim lngCounter As Long
   
   ' Set default values
   Err.Clear
   Convert_STRtoHEX = ""
   
   ' Loop through the string and convert it to HEX 1 character at a time
   For lngCounter = 1 To Len(StringToConvert)
      Convert_STRtoHEX = Convert_STRtoHEX & Right("0" & CStr(Hex(Asc(Mid(StringToConvert, lngCounter, 1)))), 2)
   Next
   
End Function

' Function that takes a string and takes it letter by letter and converts it
' the string value equivelent... and then returns the string of characters
Private Function Convert_HEXtoSTR(ByVal HexToConvert As String, _
                                 Optional ByVal blnContinueOnError As Boolean = True, _
                                 Optional ByRef Return_ErrorOccured As Boolean = False) As String
On Error GoTo ErrorTrap
   
   Dim lngCounter As Long
   
   ' Set default values
   Err.Clear
   Convert_HEXtoSTR = ""
   Return_ErrorOccured = False
   
   ' Make sure the string has the right number of characters (devisible by 2 evenly)
   If Len(HexToConvert) Mod 2 <> 0 Then
      Return_ErrorOccured = True
      If blnContinueOnError = False Then Exit Function
   End If
   
   ' Loop through the string 2 characters at a time and convert the HEX to string
   For lngCounter = 1 To Len(HexToConvert) Step 2
      Convert_HEXtoSTR = Convert_HEXtoSTR & Chr(Val("&H" & Mid(HexToConvert, lngCounter, 2)))
   Next
   
   Exit Function
   
ErrorTrap:
   
   Err.Clear
   Return_ErrorOccured = True
   If blnContinueOnError = True Then
      Resume Next
   Else
      Convert_HEXtoSTR = ""
   End If
   
End Function

' Generates a random password that is used to encrypt the data
Public Function GeneratePassword(ByVal PasswordLength As Integer) As String
On Error GoTo ErrorTrap
   
   Dim INVALID_CHARS As String
   Dim lngCounter    As Long
   Dim lngChar       As Long
   
   ' Set default values
   Err.Clear
   GeneratePassword = ""
   
   ' Specify which characters are invalid
   INVALID_CHARS = Chr(34) & "%'*,./\:;<>=?&`"
   
   ' Restrict maximum password length to 256
   If PasswordLength > 256 Then PasswordLength = 256
   
   ' Generate random password
   For lngCounter = 1 To PasswordLength
      
      lngChar = 0
      Do
         Do
            Randomize Timer
            lngChar = CLng((122 - 33 + 1) * Rnd + 33)
         Loop While (lngChar < 33) And (lngChar > 122)
      Loop While InStr(1, INVALID_CHARS, Chr(lngChar), vbBinaryCompare) <> 0
      
      GeneratePassword = GeneratePassword & Chr(lngChar)
   Next
   
   Exit Function
   
ErrorTrap:
   
   If Err.Number = 0 Then      ' No Error
      Resume Next
   ElseIf Err.Number = 20 Then ' Resume Without Error
      Resume Next
   Else                        ' Other Error
      MsgBox Err.Source & " caused the following error:" & Chr(13) & Chr(13) & "Error Number = " & CStr(Err.Number) & Chr(13) & "Error Description = " & Err.Description, vbOKOnly + vbExclamation, "  Error  -  " & Err.Description
      Err.Clear
   End If
   
End Function

' Function that checks if an error occured in the last crypt related API
' called, and if there was... an error message is displayed
Private Function CheckGetLastError(ByVal ErrorNumber As Long, _
                                   Optional ByRef Return_ErrNum As Long, _
                                   Optional ByRef Return_ErrDesc As String, _
                                   Optional ByVal NameOfLastAPICalled As String = "last", _
                                   Optional ByVal ShowErrorMsg As Boolean = True) As Boolean
On Error Resume Next
   
   ' Set the default return values
   Return_ErrNum = 0
   Return_ErrDesc = ""
   CheckGetLastError = False
   
   ' Check if an error number was passed.  If none was, check for an error occurance.
   If ErrorNumber = 0 Then
      ErrorNumber = GetLastError
      If ErrorNumber = 0 Then
         Err.Clear
         Exit Function
      End If
   End If
   
   ' An Error Occured
   CheckGetLastError = True
   Return_ErrNum = ErrorNumber
   Err.Clear
   
   ' Get the error text
   Select Case ErrorNumber
      Case 0:                       Exit Function
      Case ERROR_INVALID_HANDLE:    Return_ErrDesc = "One of the parameters specifies an invalid handle."
      Case ERROR_INVALID_PARAMETER: Return_ErrDesc = "One of the parameters contains an invalid value. This is most often an illegal pointer."
      Case ERROR_NOT_ENOUGH_MEMORY: Return_ErrDesc = "The operating system ran out of memory during the operation."
      Case ERROR_BUSY:              Return_ErrDesc = "The hash object specified by hHash is currently being used by another process."
      Case NTE_BAD_ALGID:           Return_ErrDesc = "The Algid parameter specifies an algorithm that this CSP does not support."
      Case NTE_BAD_DATA:            Return_ErrDesc = "The data to be encrypted is invalid. For example, when a block cipher is used and the Final flag is FALSE, the value specified by pdwDataLen must be a multiple of the block size."
      Case NTE_BAD_FLAGS:           Return_ErrDesc = "The dwFlags parameter has an illegal value."
      Case NTE_BAD_HASH:            Return_ErrDesc = "The hash object specified by the hHash parameter is invalid."
      Case NTE_BAD_HASH_STATE:      Return_ErrDesc = "An attempt was made to add data to a hash object that is already marked 'finished'."
      Case NTE_BAD_KEY:             Return_ErrDesc = "A keyed hash algorithm (such as CALG_MAC) is specified by Algid and the hKey parameter is either zero or it specifies an invalid key handle. This error code will also be returned if the key is to a stream cipher, or if the cipher mode is anything other than CBC."
      Case NTE_BAD_KEYSET:          Return_ErrDesc = "The Registry entry for the key container could not be opened and may not exist."
      Case NTE_BAD_KEYSET_PARAM:    Return_ErrDesc = "The pszContainer or pszProvider parameter is set to an illegal value."
      Case NTE_BAD_LEN:             Return_ErrDesc = "The CRYPT_USERDATA flag is set and the dwDataLen parameter has a nonzero value."
      Case NTE_BAD_PROV_TYPE:       Return_ErrDesc = "The value of the dwProvType parameter is out of range. All provider types must be from 1 to 999, inclusive."
      Case NTE_BAD_SIGNATURE:       Return_ErrDesc = "The provider DLL signature did not verify correctly. Either the DLL or the digital signature has been tampered with."
      Case NTE_BAD_UID:             Return_ErrDesc = "The CSP context that was specified when the hash object was created cannot be found."
      Case NTE_DOUBLE_ENCRYPT:      Return_ErrDesc = "The application attempted to encrypt the same data twice."
      Case NTE_EXISTS:              Return_ErrDesc = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key container already exists."
      Case NTE_FAIL:                Return_ErrDesc = "The function failed in some unexpected way."
      Case NTE_KEYSET_ENTRY_BAD:    Return_ErrDesc = "The Registry entry for the pszContainer key container was found (in the HKEY_CURRENT_USER window), but is corrupt. See the section System Administration for details about CryptoAPI’s Registry usage."
      Case NTE_KEYSET_NOT_DEF:      Return_ErrDesc = "No Registry entry exists in the HKEY_CURRENT_USER window for the key container specified by pszContainer."
      Case NTE_NO_MEMORY:           Return_ErrDesc = "The CSP ran out of memory during the operation."
      Case NTE_PROV_DLL_NOT_FOUND:  Return_ErrDesc = "The provider DLL file does not exist or is not on the current path."
      Case NTE_PROV_TYPE_ENTRY_BAD: Return_ErrDesc = "The Registry entry for the provider type specified by dwProvType is corrupt. This error may relate to either the user default CSP list or the machine default CSP list. See the section System Administration for details about CryptoAPI’s Registry usage."
      Case NTE_PROV_TYPE_NO_MATCH:  Return_ErrDesc = "The provider type specified by dwProvType does not match the provider type found in the Registry. Note that this error can only occur when pszProvider specifies an actual CSP name."
      Case NTE_PROV_TYPE_NOT_DEF:   Return_ErrDesc = "No Registry entry exists for the provider type specified by dwProvType."
      Case NTE_PROVIDER_DLL_FAIL:   Return_ErrDesc = "The provider DLL file could not be loaded, and may not exist. If it exists, then the file is not a valid DLL."
      Case NTE_SIGNATURE_FILE_BAD:  Return_ErrDesc = "An error occurred while loading the DLL file image, prior to verifying its signature."
      Case Else:                    Return_ErrDesc = "Unknown Error"
   End Select
   
   ' Display the error
   If ShowErrorMsg = True Then
      MsgBox "The " & NameOfLastAPICalled & " Windows API caused the following error:" & Chr(13) & Chr(13) & "Error Number = " & CStr(ErrorNumber) & Chr(13) & "Error Description = " & Return_ErrDesc, vbOKOnly + vbExclamation, "  Windows API Error"
   End If

End Function

Private Function ContainsNonNumeric(ByVal StringToCheck As String) As Boolean
   
   Dim lngCounter As Long
   
   For lngCounter = 1 To Len(StringToCheck) Step 10
      If IsNumeric(Mid(StringToCheck, lngCounter, 10)) = False Then
         ContainsNonNumeric = True
         Exit For
      End If
   Next
   
End Function
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

baseado no post do Quintas, vai ficar +/- assim a classe criadora do XML para quem vai usar sem txt

Código: Selecionar todos

#include "hbclass.ch"
#include "hbcompat.ch"

CREATE CLASS hbNFeCreator
   DATA Chave            INIT "" EXPORTED
   DATA Ide                      EXPORTED
   DATA Emi                      EXPORTED
   DATA Dest                     EXPORTED
   DATA Retirada                 EXPORTED
   DATA Entrega                  EXPORTED
   DATA ICMSTotal                EXPORTED
	DATA ISSTotal                 EXPORTED
	DATA RetTrib                  EXPORTED
	DATA Transp                   EXPORTED
	DATA RetTransp                EXPORTED
	DATA VeicTransp               EXPORTED
	DATA Reboque                  EXPORTED
	DATA Fatura                   EXPORTED
	DATA Duplicatas               EXPORTED
	DATA InfAdic                  EXPORTED
	DATA ObsCont                  EXPORTED
	DATA ObsFisco                 EXPORTED
	DATA ProcRef                  EXPORTED
   DATA Exporta                  EXPORTED
	DATA Compra                   EXPORTED
	DATA InfProt                  EXPORTED

   DATA nItens
   DATA Item                     EXPORTED

   METHOD New()                  CONSTRUCTOR
   METHOD AddItem()
   METHOD getCurItem()
ENDCLASS

METHOD New() CLASS hbNFeCreator
   ::nItens := 0
   ::Chave := ""
   ::Item := hash()
   ::Emi := TypeEmitente():New()
RETURN Self

METHOD AddItem() CLASS hbNFeCreator
   ::nItens ++
   ::Item[ALLTRIM(STR(::nItens))] := TypeItem():New()
RETURN

METHOD getCurItem() CLASS hbNFeCreator
RETURN ALLTRIM(STR(::nItens))


CREATE CLASS TypeEmitente FROM hbNFeCreator
   DATA Nome
   DATA Endereco
   DATA Cidade
   DATA UF

   METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New() Class TypeEmitente
 ::Nome := ""
 ::Endereco := ::Cidade := ::UF := ""
RETURN SELF

CREATE CLASS TypeItem FROM hbNFeCreator
   DATA cProd
   DATA xProd
   DATA nItensDI
   DATA ItemDI             EXPORTED

   METHOD New() CONSTRUCTOR
   METHOD AddDI()
   METHOD getCurDI()
ENDCLASS

METHOD New() CLASS TypeItem
 ::cProd := ::xProd := ""
 ::nItensDI := 0
 ::ItemDI:=hash()
RETURN SELF

METHOD AddDI() CLASS TypeItem
   ::nItensDI ++
   ::ItemDI[ALLTRIM(STR(::nItensDI))] := TypeItemDI():New()
RETURN

METHOD getCurDI() CLASS TypeItem
RETURN ALLTRIM(STR(::nItensDI))

CREATE CLASS TypeItemDI FROM hbNFeCreator
   DATA nDI                  AS STRING

   METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New() Class TypeItemDI
 ::nDI := ""
RETURN SELF



FUNC MAIN()
   oNF := hbNFeCreator():New()
   oNF:Emi:Nome = "TESTE"
   oNF:AddItem()
   oNF:Item[oNF:getCurItem()]:cProd := 'a'
   oNF:Item[oNF:getCurItem()]:AddDI()
   oNF:Item[oNF:getCurItem()]:ItemDI[oNF:Item[oNF:getCurItem()]:getCurDI()]:nDI := '123'
   oNF:AddItem()
   oNF:Item[oNF:getCurItem()]:cProd := 'b'
   oNF:Item[oNF:getCurItem()]:AddDI()
   oNF:Item[oNF:getCurItem()]:ItemDI[oNF:Item[oNF:getCurItem()]:getCurDI()]:nDI := '456'
   ? "Emitente:" + oNF:Emi:Nome
   FOR nI = 1 TO oNF:nItens
      cNi := ALLTRIM(STR(nI))
      ? "Item    :" + oNF:Item[cNi]:cProd
      FOR nI2 = 1 TO oNF:Item[cNi]:nItensDI
         cNi2 := ALLTRIM(STR(nI2))
         ? "DI      :" + oNF:Item[cNi]:ItemDI[cNi2]:nDI
      NEXT
   NEXT
RETURN
alguma sugestão no código?

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

acredito que ficou melhor com o hash numerico

Código: Selecionar todos

#include "hbclass.ch"
#include "hbcompat.ch"

CREATE CLASS hbNFeCreator
   DATA Chave            INIT "" EXPORTED
   DATA Ide                      EXPORTED
   DATA Emi                      EXPORTED
   DATA Dest                     EXPORTED
   DATA Retirada                 EXPORTED
   DATA Entrega                  EXPORTED
   DATA ICMSTotal                EXPORTED
	DATA ISSTotal                 EXPORTED
	DATA RetTrib                  EXPORTED
	DATA Transp                   EXPORTED
	DATA RetTransp                EXPORTED
	DATA VeicTransp               EXPORTED
	DATA Reboque                  EXPORTED
	DATA Fatura                   EXPORTED
	DATA Duplicatas               EXPORTED
	DATA InfAdic                  EXPORTED
	DATA ObsCont                  EXPORTED
	DATA ObsFisco                 EXPORTED
	DATA ProcRef                  EXPORTED
   DATA Exporta                  EXPORTED
	DATA Compra                   EXPORTED
	DATA InfProt                  EXPORTED

   DATA nItens
   DATA Item                     EXPORTED

   METHOD New()                  CONSTRUCTOR
   METHOD AddItem()
   METHOD getCurItem()
ENDCLASS

METHOD New() CLASS hbNFeCreator
   ::nItens := 0
   ::Chave := ""
   ::Item := hash()
   ::Emi := TypeEmitente():New()
RETURN Self

METHOD AddItem() CLASS hbNFeCreator
   ::nItens ++
   ::Item[::nItens] := TypeItem():New()
RETURN

METHOD getCurItem() CLASS hbNFeCreator
RETURN ::nItens


CREATE CLASS TypeEmitente FROM hbNFeCreator
   DATA Nome
   DATA Endereco
   DATA Cidade
   DATA UF

   METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New() Class TypeEmitente
 ::Nome := ""
 ::Endereco := ::Cidade := ::UF := ""
RETURN SELF

CREATE CLASS TypeItem FROM hbNFeCreator
   DATA cProd
   DATA xProd
   DATA nItensDI
   DATA ItemDI             EXPORTED

   METHOD New() CONSTRUCTOR
   METHOD AddDI()
   METHOD getCurDI()
ENDCLASS

METHOD New() CLASS TypeItem
 ::cProd := ::xProd := ""
 ::nItensDI := 0
 ::ItemDI:=hash()
RETURN SELF

METHOD AddDI() CLASS TypeItem
   ::nItensDI ++
   ::ItemDI[::nItensDI] := TypeItemDI():New()
RETURN

METHOD getCurDI() CLASS TypeItem
RETURN ::nItensDI

CREATE CLASS TypeItemDI FROM hbNFeCreator
   DATA nDI                  AS STRING

   METHOD New() CONSTRUCTOR
ENDCLASS

METHOD New() Class TypeItemDI
 ::nDI := ""
RETURN SELF



FUNC MAIN()
   oNF := hbNFeCreator():New()
   oNF:Emi:Nome = "TESTE"
   oNF:AddItem()
   oNF:Item[oNF:getCurItem()]:cProd := 'a'
   oNF:Item[oNF:getCurItem()]:AddDI()
   oNF:Item[oNF:getCurItem()]:ItemDI[oNF:Item[oNF:getCurItem()]:getCurDI()]:nDI := '123'
   oNF:AddItem()
   oNF:Item[oNF:getCurItem()]:cProd := 'b'
   oNF:Item[oNF:getCurItem()]:AddDI()
   oNF:Item[oNF:getCurItem()]:ItemDI[oNF:Item[oNF:getCurItem()]:getCurDI()]:nDI := '456'
   ? "Emitente:" + oNF:Emi:Nome
   FOR nItem = 1 TO oNF:nItens
      ? "Item    :" + oNF:Item[nItem]:cProd
      FOR nItemDI = 1 TO oNF:Item[nItem]:nItensDI
         ? "DI      :" + oNF:Item[nItem]:ItemDI[nItemDI]:nDI
      NEXT
   NEXT
RETURN
[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Classe para NFe alguem tem interesse?

Mensagem por JoséQuintas »

Atenção: como eu disse, aqueles foram sendo testes, mas me explicaram bem no grupo google/Harbour.

Class AlgumaCoisa FROM OutraCoisa

Esse FROM equivale a declaração de herança, e cria uma nova classe igual a indicada, acrescentando os novos dados/métodos.
Eu estava usando no teste, mas é errado para esse caso.
Exemplos que me passaram foram as classes de FTP e HTTP, onde elas se baseiam na TCPIP.
A FTP usa o FROM, pra criar uma FTP com tudo da TCPIP e mais o específico de FTP
E a HTTP, com tudo da TCPIP e mais o específico de HTTP.

Pessoalmente, acho que só definir a classe pra variável já fica interessante.
Veja alguns usos da variável, onde as funções nem precisam fazer parte da classe, e podem permitir expandir opções sem deixá-la pesada, e até deixando todas padronizadas, por usar a classe com os campos da nota

varNotaFiscal := XmlToVar(MemoRead("arquivo.xml"))
varNotaFiscal := TxtToVar(MemoRead("arquivo.txt"))
varNotaFiscal := IniToVar(MemoRead("arquivo.ini"))

MemoWrit("arquivo.xml",VarToXml(varNotaFiscal))
MemoWrit("arquivo.txt",VarToTxt(varNotaFiscal))
MemoWrit("arquivo.ini",VarToIni(varNotaFiscal))

GeraPdf(varNotaFiscal)

ValidaOk := ValidaDados(varNotaFiscal)
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Classe para NFe alguem tem interesse?

Mensagem por JoséQuintas »

Só um comentário extra sobre assinatura digital:

É interessante ver que é o Windows é que faz a assinatura.
A CAPICOM é um componente contendo APIs de acesso à Criptografia do Windows, segundo a Microsoft pra "facilitar" o uso.
Algo como funções "mais simples", que na prática também são complicadas... rs
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

é Quintas nem percebi que o FROM é a mesma coisa do INHERIT, mas da nada não
pela lógica que fiz é só tirar o FROM, nao precisa de herança tudo pode ficar na classe principal
as demais podem ser secundarias
se bem que a herança nao tinha muito problema pois um new substitui o outro, só iriam vir os DATA praticamente
eu particularmente prefiro ter uma classe no lugar dos ini do acbr eu fiz mais por compatibilizar o que ja usava e que muitos usam tb
mas vc me deu a luz que faltava

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

me entristeceu a pouca adesão ao projeto, o pessoal reclamava tanto que o harbour nao consumia WS, agora que esta ninguem se manifesta, estarei mantendo o projeto para os interessados e para mim, poderia ser um projeto melhor se tivesse um pouquinho de colaboração do pessoal afinal ainda somos uma grande comunidade

quem tiver interesse em CTe, NFSe, pode me chamar em pvt

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Classe para NFe alguem tem interesse?

Mensagem por janio »

Fernando!

Fica triste nao. Deu pra ver o quanto vc se dedicou a esse projeto e de uma coisa eu tenho certeza: Vc pode se orgulhar pq o que NINGUEM conseguiu fazer em xharbour, vc conseguiu!

Agora, vou falar por mim e acho que é o que está acontecendo com a grande maioria dos colegas. Eu tenho tudo funcionando uma maravilha com ACBr, e PRIMEIRO: estou sem tempo pra testar qq coisa, e SEGUNDO: Pelo menos por enquanto eu nao queria mexer em algo que está funcionando.

Talvez esse projeto tenha chegado um pouco tarde... não sei! Quem vai iniciar agora uma solução para nfe, seu projeto é uma mão na roda. Mas pra quem já tem algo funcionando e sem dar problema... talvez nao queira mudar agora.

Quando eu tiver um tempinho vou dar uma olhada.

Janio
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
mbrigatti
Usuário Nível 2
Usuário Nível 2
Mensagens: 68
Registrado em: 16 Set 2005 08:13
Localização: Piracicaba - SP

Classe para NFe alguem tem interesse?

Mensagem por mbrigatti »

Fernando,

Não é que não haja interesse não, eu particularmente estou meio atolado de compromissos, mas estou colaborando no que posso, e por enquanto fiquei só no Help para ir vendo no geral o que estava sendo feito.
Mas a comunidade é grande e tem muita gente acompanhando e aguardando para poder usar.
Tenho interesse nos próximos projetos e pretendo continuar colaborando.
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

Janio
valew
no meu caso eu tinha em acbr, funcionar funcionava, mas alem do inconveniente de ter instalado um mediador, o retorno não era 100% fora a velocidade, tenho varios clientes de nfe e a maioria tem varios pcs para faturamento, estava dando muito trabalho, para mim esta ajudando fora que os clientes gostaram da velocidade, esse mes quero terminar colocando em todos meus clientes, mas entendo seu ponto de vista, eu deixei das 2 maneiras no meu sistema pois ja trabalhava com os ini do acbr, foi uma boa experiencia, só não sei se valeu a pena, não gostaria de ver esse codigo se decompondo por ai

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Classe para NFe alguem tem interesse?

Mensagem por sygecom »

Olá Fernando,

Desanima não, tem gente que usa e nem se manifesta, assim funciona com Hwgui, LetoDB e etc...ainda mais que o projeto está bem completo.

Particularmente vou começar usando pela carta de correção já, e deixar meu sistema compatível com ACBR e com HBNFE e vou liberar em alguns clientes com HBNFE para acompanhar as dificuldades.

Uma grande dificuldade do pessoal é criar XML, e quanto a isso o projeto está compatível com ENTNFE.TXT do ACBR que é um ponto a mais, porem o pessoal do CLIPPER não podem se beneficiar ainda do projeto por que não migraram para Harbour e as vez nem sabem compilar com Harbour, então teria que futuramente criar um hbnfemonitor.exe compatível com os comandos do ACBRNFEMONITOR e com o TXT do emissor do sefaz de SP.

É um projeto que está no começo, não desanima que isso ainda vai dar muito o que fala.
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
athayde
Colaborador
Colaborador
Mensagens: 166
Registrado em: 14 Fev 2007 16:54

Classe para NFe alguem tem interesse?

Mensagem por athayde »

tomada Leonardo
nao é um desanimo total só pensei q iria repercurtir mais, visto que é um compenente built-in como o acbr para quem trabalha com delphi
eu com certeza vou utilizar e muito, pois quero ter controle sobre tudo em meu software, hj testei num cliente com A3 e funfou legal, precisava de umas pessoas com partilha e outras coisas diferentes para ficar bem filé, o projeto vai continuar a evoluir pois estou usando a todo vapor, só não vou colocar CTe e NFSe nele pois eu não uso, mas se pintar alguem podemos estudar o caso

[]s
Fernando
projeto hbNFe NFe para [x]Harbour venha fazer parte do time http://www.pctoledo.com.br/forum/viewforum.php?f=54
Harbour 3.2 + Hwgui (HBIDE)
Responder