Italian [B4X] SD p7m (Fattura elettronica)

Star-Dust

Expert
Licensed User
Longtime User
Con l'avvento della Fattura Elettronica ( :confused: ) è nato il bisogno di leggere i file p7m (che arrivano nella posta certificata se non hai un portale con codice univoco)
Il formato del p7m della fattura elettronica (fortunatamente) non è codificata/crittografata.

Con questa libreria ho voluto creare uno strumento che estrae il file XML e/o eventuali allegati PDF della fattura elettronica.


SD_p7m

Author: Star-Dust
Version: 0.05
  • ParseXml
    • Functions:
      • Class_Globals As String
      • ErrorXML As Map
      • Initialize (XML As String) As String
        Initializes the object. You can add parameters to this method if needed.
      • IsInitialized As Boolean
        Verifica se l'oggetto sia stato inizializzato.
      • ProperXML As String
  • XMLTreeView
    • Functions:
      • BringToFront As String
      • Class_Globals As String
      • DesignerCreateView (Base As Object, Lbl As Label, Props As Map) As String
        Base type must be Object
      • Initialize (Callback As Object, EventName As String) As String
      • Invalidate As String
      • IsInitialized As Boolean
        Verifica se l'oggetto sia stato inizializzato.
      • RenderXML (XMLtext As String) As String
      • RequestFocus As String
      • SendToBack As String
      • Snapshot As B4XView
    • Properties:
      • Enable As Boolean
      • Height As Int
      • Left As Int
      • Tag As Object
      • Top As Int
      • Visible As Boolean
      • Width As Int
  • p7m
    • Fields:
      • CharSet As String
    • Functions:
      • AllegatoFileName As String
      • AllegatoRaw As Byte()
      • AllegatoToString As String
      • Class_Globals As String
      • Initialize (Path As String, FileName As String) As String
        Initializes the object. You can add parameters to this method if needed.
      • IsInitialized As Boolean
        Verifica se l'oggetto sia stato inizializzato.
      • xlmByte As Byte()
      • xlmString As String

B4X:
Sub Decode(Path As String, NomeXML As String)
    Dim p7m_fe As sd_p7m

    p7m_fe.Initialize(Path,NomeXML)
 
 
    File.WriteString(File.DirApp,NomeXML.Replace(".p7m",""),p7m_fe.xlmString)
    If p7m_fe.xlmString.IndexOf("<Attachment>")>-1 Then
        ' Se c'è allegato lo salvo
        File.WriteString(File.DirApp,p7m_fe.AllegatoFileName,p7m_fe.AllegatoToString)
    End If
End Sub

PS. Ovviamente non è adatto a file p7m che non siano fatture elettroniche per potrebbero essere criptati. E sempre ovviamente non verifica la certificazione del documento.
 

Attachments

  • SD_p7m 0.05.zip
    12.6 KB · Views: 439
  • jSD_p7m 0.05.zip
    12.7 KB · Views: 426
  • iSD_p7m 0.05.zip
    215 KB · Views: 380
Last edited:

Lello1964

Well-Known Member
Licensed User
Longtime User
Con l'avvento della Fattura Elettronica ( :confused: ) è nato il bisogno di leggere i file p7m (che arrivano nella posta certificata se non hai un portale con codice univoco)
Il formato del p7m della fattura elettronica (fortunatamente) non è codificata/crittografata.

Con questa libreria ho voluto creare uno strumento che estrae il file XML e/o eventuali allegati PDF della fattura elettronica.

jSD_p7m

Author: Star-Dust
Version: 0.01
  • sd_p7m
    • Functions:
      • AllegatoFileName As String
      • AllegatoRaw As Byte()
      • AllegatoToString As String
      • Class_Globals As String
      • Initialize (Path As String, FileName As String) As String
        Initializes the object. You can add parameters to this method if needed.
      • IsInitialized As Boolean
        Verifica se l'oggetto sia stato inizializzato.
      • xlmByte As Byte()
      • xlmString As String

B4X:
Sub Decode(Path As String, NomeXML As String)
    Dim p7m_fe As sd_p7m

    p7m_fe.Initialize(Path,NomeXML)
    File.WriteBytes(File.DirApp,NomeXML.Replace(".p7m",""),p7m_fe.xlmByte) ' elimina .p7m dal nome file
    If p7m_fe.xlmString.IndexOf("<Attachment>")>-1 then File.WriteString(File.DirApp,p7m_fe.AllegatoFileName,p7m_fe.AllegatoToString) ' Allegato
End Sub

PS. Ovviamente non è adatto a file p7m che non siano fatture elettroniche per potrebbero essere criptati. E sempre ovviamente non verifica la certificazione del documento.

Mi da questo errore nell'ultima riga
B4X:
    Dim p7m_fe As sd_p7m

    p7m_fe.Initialize(Path,NomeXML)
   File.WriteBytes(Path,NomeXML.Replace(".p7m",""),p7m_fe.xlmByte) ' elimina .p7m dal nome file
   If p7m_fe.xlmString.IndexOf("<Attachment>")>-1 Then File.WriteString(Path,p7m_fe.AllegatoFileName,p7m_fe.AllegatoToString) ' Allegato

java.lang.StringIndexOutOfBoundsException: length=17758; index=-1
at java.lang.String.substring(String.java:2029)
at b4a.example.sd_p7m._vv7(sd_p7m.java:432)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at Aruba.Fatture.main._decode(main.java:2091)
at Aruba.Fatture.main$ResumableSub_LeggiPerNome.resume(main.java:2530)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
at anywheresoftware.b4a.BA$2.run(BA.java:370)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
 

Lello1964

Well-Known Member
Licensed User
Longtime User
Ti allego il p7m che ho provato, ho rimosso i dati sensibili !!

e l'ho rinominato in .txt era p7m
 

Attachments

  • IT02663950984_6qnhV.xml.txt
    18.9 KB · Views: 391

Star-Dust

Expert
Licensed User
Longtime User
Il file in genere inizia con questa dicitura:
<?xml version="1.0" encoding="utf-8"?><p:FatturaElettronica versione="FPR12"
Ma il tuo inizia così:
<p:FatturaElettronica versione="FPR12"
Non so se lo hai modificato tu, oppure è una variante. Cmq tutti i file XML devono iniziare con la dicitura ?XML, in ogni caso andrebbe aggiunta per rendere il file XML leggibile e riconoscibile ai software di lettura.

Comunque aggiungerò alla libreria la gestione di questi errori
 

Star-Dust

Expert
Licensed User
Longtime User
Mi da questo errore nell'ultima riga
B4X:
    Dim p7m_fe As sd_p7m

    p7m_fe.Initialize(Path,NomeXML)
   File.WriteBytes(Path,NomeXML.Replace(".p7m",""),p7m_fe.xlmByte) ' elimina .p7m dal nome file
   If p7m_fe.xlmString.IndexOf("<Attachment>")>-1 Then File.WriteString(Path,p7m_fe.AllegatoFileName,p7m_fe.AllegatoToString) ' Allegato

java.lang.StringIndexOutOfBoundsException: length=17758; index=-1
at java.lang.String.substring(String.java:2029)
at b4a.example.sd_p7m._vv7(sd_p7m.java:432)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:180)
at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:262)
at Aruba.Fatture.main._decode(main.java:2091)
at Aruba.Fatture.main$ResumableSub_LeggiPerNome.resume(main.java:2530)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:137)
at anywheresoftware.b4a.BA$2.run(BA.java:370)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6810)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Comunque l'ultima riga non è necessaria, serve solo per gli allegati. Prova a toglierla.

Il file che mi hai inviato sembra non sia conforme allo standard XML. Penso sia stato modificato troppo.
 

Star-Dust

Expert
Licensed User
Longtime User
Posso confermarti che il formato XML del tuo file è un tipo particolare.
Anche se dovrebbe avere l'Header <?XML, indicando anche la versione sembra anche che alcuni non lo mettano.
Ho adattato il codice per questa variante.

Inoltre nel testo sono inserti dei caratteri ASCII anomali chr(65533) e Chr(3) ecc..... Questo manda in errore i lettori XML, forse qualcosa di errato nella lettura del file da ruba.
Ho inserito una funzione per eliminare questi errori.

Presto pubblicherò un aggiornamento.
 

Star-Dust

Expert
Licensed User
Longtime User
Aggiornamento a 0.02

P.S. Non ci saranno ulteriori aggiornamenti a questa libreria. Sono sicuro che con le informazioni che ho condiviso potrete svilupparne una anche migliore. Questo è stato un passatempo domenica. ;)
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Sembra che alcuni caratteri casuali che sembra appaiono sul file XML dipendano dal tipo del CharSet selezionato per decodicare. Di standard uso UTF-8, ma ci sono anche Windows-1251, Windows-1252, ISO-8859-1, ISO-8859-9.....

Creerò una versione che permetta di selezionare il CharSet.
 

Star-Dust

Expert
Licensed User
Longtime User
Update 0.03

Ho introdotto la proprietà CharSet di tipo stringa che di default ha il valore UTF8 ma che può essere modificata solo con un assegnazione dopo l'inizializzazione.

B4X:
Dim p7m_fe As sd_p7m

p7m_fe.Initialize(Path,NomeXML)
log(p7m_fe.xlmString)

p7m_fe.CharSet="ISO-8859-4"
log(p7m_fe.xlmString)

p7m_fe.CharSet="WINDOWS-1251"
log(p7m_fe.xlmString)
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Update 0.04
 

Star-Dust

Expert
Licensed User
Longtime User
Prossimamente pubblicherò una libreria che verifica se XML contiene errori, li corregge e infine visualizza il file in formato albero(tree) e in formato fattura
 

Star-Dust

Expert
Licensed User
Longtime User
un anteprima
ezgif.com-optimize.gif
upload_2019-5-22_22-11-30.png
 

Star-Dust

Expert
Licensed User
Longtime User
Rilasciata la versione 0.05

Verifica errori

B4X:
Private Parse As ParseXml
Private Parse As ParseXml
Private XMLText as String

p7m_fe.Initialize(File.DirAssets,NomeXML)
XMLText=p7m_fe.xlmString
Parse.Initialize(XMLText)
If Parse.ErrorXML.Size>0 Then XMLText=Parse.ProperXML
In ErrorXML gli errori delle etichette vengono restituiti in una Mappa, dove la chiave è l'apertura etichetta e il valore è la chiusura, che ovviamente non corrisponderanno essendoci un errore.
ProperXML invece verifica ogni etichetta e se ci sono discordanze le corregge

Vista con l'albero rappresentativo del file XML
B4X:
XMLTreeView1.RenderXML(XMLText)
 
Last edited:

Lello1964

Well-Known Member
Licensed User
Longtime User
[RISOLTO]

L'ultima release non funziona più, non viene ricosciuta la libreria.

errore :
tipo sconosciuto sd_p7m
Manca un riferimento ad una libreria?

malgrado sia selezionata nella lista delle librerie
??

è cambiato il nome da sd_p7m a p7m
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Hai forse sbagliato la dichiarazione?
B4X:
Dim p7m_fe As p7m
Il tipo non è più SD_pm7 ma solo pm7 perchè su B4idava problemi il carattere undescore
 

Star-Dust

Expert
Licensed User
Longtime User
Do you have an English version of this interesting thing. I happen to speak Xhosa and as interesting as this seems, m blank. :)
Electronic invoices are an Italian complication.
Here nobody considers it interesting but annoying.:p

What can you do?
 

Xfood

Expert
Licensed User
Prossimamente pubblicherò una libreria che verifica se XML contiene errori, li corregge e infine visualizza il file in formato albero(tree) e in formato fattura
Gentilissimo @Star-Dust potresti postare un esempio in B4A di visualizzazione fattura elettronica " in formato Fattura"?
utilizzando la tua magnifica libreria.. Te ne sarei molto grato
Grazie.
 
Top