Fattura Elettronica in VB6 o export xml

di il
25 risposte

Fattura Elettronica in VB6 o export xml

Salve a tutti, spero possiate essermi di aiuto in questo argomento che vede coinvolti molti sviluppatori vb6 ancora duri a morire! Qualcuno di voi ha già gestionali di fatturazione nei quali ha integrato l'esportazione del file xml da inviare al SDI come procedura vuole? Se si, avete acquistato librerie o progetti open source che ci consentano di non buttare alle ortiche gestionali perfettamente funzionanti che che non emettono xml? Spero in un confronto con chi come me sta percorrendo questa strada, nella speranza di non vedere vanificato il lavoro di tanti anni, perchè non so davvero da dove iniziare e ciò che ho visto sul sito dell'agenzia delle entrate mi ha più confuso che chiarito le idee.
Ciò che peraltro vorrei realizzare è la sola esportazione dei dati nel formato legale xml, lascerò che la trasmissione e la conservazione rimanga ai soggetti abilitati che sceglieranno i clienti. Aggiungo che ho trovato su un sito (non so se posso indicare l'url) due librerie perfettamente funzionanti e adatte all'esportazione, ma credo che l'autore, oltretutto validissimo, abbia abbandonato il progetto già nel 2015 e pertanto non tiene conto dei nuovi formati che nel frattempo l'agenzia delle entrate ha introdotto, e delle librerie non c'è un sorgente ma le dll già compilate.

Vi ringrazio in anticipo
Jay

25 Risposte

  • Re: Fattura Elettronica in VB6 o export xml

    Creare xml è il problema minore.
    non è altro che un file di testo.
    personalmente, volutamente, non uso alcuna libreria xml, ma lo genero 'a mano', così da avere il controllo perfetto di ogni singolo carattere.
    se i documenti non sono complessi basta una giornata per fare lo esportatore xml.

    Il 'dramma' riguarda la procedura di invio, e la ricezione.
    infatti molti si concentrano su invio, ma in quel caso si può giocare al ribasso, col minimo indispensabile.

    In ricezione invece bisogna prevedere ogni possibilità, e sono parecchie.

    Personalmente uso la documentazione in formato xls della agenzia entrate, ragionevolmente chiara.
    più il programma java ufficiale (sempre ade) per vedere come genera i casi particolari.
    ovviamente a raffica il sitarello ade per i controlli di conformità col captcha
  • Re: Fattura Elettronica in VB6 o export xml

    Grazie per il chiarimento, ma per me le cose stanno in maniera diversa. Ho intenzione di lasciare ai web service la gestione di ricezione inoltro e conservazione. Tutto ciò che mi necessita organizzare, è la generazione di un xml 'in chiaro' da inviare al preposto, sia esso commercialista o web service che firmerà il documento e lo invierà al sdi.
    Il fatto è che non so neppure da dove iniziare, come gestire e dove eventualmente trovare qualche pezza d'appoggio fatto salvo il pdf dell'ade nel quale viene descritta la tipologia di campi necessari. Per questa ragione chiedevo supporto o materiale utilizzabile da chi ha già esperienza.
  • Re: Fattura Elettronica in VB6 o export xml

    Il file xml non è altro che un file di solo testo.
    Se vuoi sapere come compilarlo ti suggerisco di studiare preliminarmente come è fatto quello di esempio della agenzia delle entrate.
    basta che lo apri col notepad.

    Personalmente la prima cosa che ho fatto è una procedura delphi che ha generato lo stesso identico file (con spazi e tutto)

    Dopo aver clonato perfettamente il file di esempio ho arricchito con i campi che mi erano necessari, attingendo dalla documentazione xls della agenzia.

    Per i casi più strani ho scaricato il programma java ufficiale della agenzia entrate, ho messo i dati che mi servivano, per poi studiare lo xml generato.

    A quel punto ho implementato le modifiche nel mio programma fino a generare un xml identico a quello del programma agenzia entrate (con gli stessi input).

    Complessivamente un 3 giornate di lavoro
  • Re: Fattura Elettronica in VB6 o export xml

    Ecco! Per quello che dico che tu sei bravo e io no!
    E' proprio quello che vorrei realizzare, ma credimi, non so neppure da dove cominciare. Ho aperto anche io il file dell'AdE, ma l'unica cosa che mi è risultata subito chiara, è che ci sono parecchi campi in più rispetto ad un normale modulo fattura così come emesso dai normali gestionali, e questo ok, inserirò i vari campi nel db e amen. Ho appena trovato una porzione di codice per la creazione di un xml ed è già qualcosa. Adesso vedrò di prendere il tracciato che l' ade mette a disposizione e proverò ad integrarlo.
    Se hai qualche maniera che possa aiutarmi ulteriormente o una porzione di codice te ne sarei davvero grato.

    Saluti
  • Re: Fattura Elettronica in VB6 o export xml

    Nel pomeriggio ti posto una vecchia versione delphi, dovrei averla in giro.
    in realtà è molto più semplice di quello che sembra, essenzialmente ti serve un 'qualcosa' in grado di scrivere una normalissima sequenza di righe di testo.
    Ti renderai conto subito che è un dramma poco drammatico
  • Re: Fattura Elettronica in VB6 o export xml

    Bon allora per dare una vaga idea
    la fattura è generata in una struttura che si chiama tstringlist, che è... una lista di stringhe, cui si accede essenzialmente con add per aggiungere gli elementi e [] per accedervi come fosse un array.

    Dentro i_dataset si attinge al database, mappando i relativi campi entro quelli della fattura elettronica
    
    function  xg_generaFatturaElettronica(i_dataset:TDataSet;i_cartella:string;i_allegato:string;
    i_trasmittentecf:string;
    i_trasmittentepiva:string;
    (...) tantl altri bei parametri di input
    
    var
       (...) varie variabili stringa
    
       anno,mese,giorno:word;
       fattura  : TStringList; //// qui materialmente viene costruita la fattura
    
       fatturadata:tdate;
       fatturanumero:integer;
       fatturaanno:integer;
       numerolinea:Integer;
       
    Funzioncine di supporto: trasforma i float nel formato della agenzia, con arrotondamento euro
    
    function g_moneyafel(i_valore:double):string;
    begin
       Result:=stringreplace(format('%.02f',[EuroArrotonda(i_valore)]),',','.',[rfreplaceall]);
    end;
    
    Questa funziona "trasforma" tutti i caratteri in formato compatibile XML
    
    function g_testoafel(i_stringa:string):string;
    var
       i:Integer;
    begin
       Result:=i_stringa;
       if i_stringa='' then Exit;
    
       for i:=Low(arrayconversione) to High(arrayconversione) do
           Result:=StringReplace(result,arrayconversione[i],'&#'+inttostr(i)+';',[rfreplaceall]);
       Result:=StringReplace(result,'<','<',[rfreplaceall]);
       Result:=StringReplace(result,'&','&',[rfreplaceall]);
       Result:=StringReplace(result,'"','"',[rfreplaceall]);
       Result:=StringReplace(result,'''','&apos;',[rfreplaceall]);
       Result:=StringReplace(result,#10,' ',[rfreplaceall]);
       Result:=StringReplace(result,#13,' ',[rfreplaceall]);
    end;
    
    Qui parte il resto
    
    var
    
       zrighe:TZQuery;
       nomefile:string;
       marchiofile:string;
       nomepdf:string;
    begin
       Result:='';
       numerolinea:=1;
       
       (...) controlli vari che tolgo
       
       fatturadata:=i_dataset.fieldbyname('datadocumento').asdatetime;
       fatturanumero:=i_dataset.fieldbyname('progressivo').asinteger;
    
       DecodeDate(fatturadata,anno,mese,giorno);
       fatturaanno:=anno;
    
       if i_dataset.fieldbyname('felpecdestinatario').isnull
           AND i_dataset.fieldbyname('felcodice').isnull then
       begin
           logganow('Errore 71734 felpecdestinatario e felcodice vuoti');
           exit;
       end;
    
    nota: c'è una funzione per generare il numero di serie aggiunto al nome file, ed è questa
    
    function Dec_To_Base(nBase,nDec_Value, Lead_Zeros: int64): string;
    var
      Base_PChar: PChar;
      Base_String: string;
      To_Del, Modulus, DivNo: int64;
      temp_string: string;
      i:integer;
      nLen, Len_Base: int64;
    begin
      {initialise..}
       BASE_string := '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';  //base62
      To_Del := 0;
      Modulus := 0;
      DivNo := nDec_Value;
      result := '';
      if (nBase > 62) then
        nBase := 62; {max = Base62}
      SetLength(Base_String, nBase);
      Base_PChar := PChar(Base_String);
      while DivNo > 0 do
      begin
        Modulus := DivNo mod nBase; 
        result := Base_PChar[Modulus] + result;
        DivNo := DivNo div nBase;
      end;
      if (Length(result) = 0) then
        result := '0';
      if (Length(result) < Lead_Zeros) then
        for i := 1 to (Lead_Zeros - Length(result)) do
          result := '0' + result;
    end; 
    
    function g_codificanumerofatturaelettronica(i_tipodocumento:string;i_anno:Integer;i_numero:Integer):string;
    var
       tipo:char;
       anno:Char;
       numero:string;
    begin
       Result:='';
       if Length(i_tipodocumento)>1 then
           Exit;
       tipo:=i_tipodocumento[1];
       if i_anno<2018 then
           Exit;
       if i_anno>(2018+62) then
           Exit;
       if i_numero<0 then
           Exit;
       if i_numero>238327 then
           Exit;
    
       anno:=Dec_To_Base(62,i_anno-2018,0)[1];
       numero:=Dec_To_Base(62,i_numero,3);
       Result:=tipo+anno+numero;
       if length(result)<>5 then
           result:='';
       end;
    

    Essenzialmente "impacchetta" tipodocumento, anno e numero fattura in 5 caratteri,
    arrivando al 2080 con circa 230.000 documento\anno massimo
    E' importante segnalare "documento" perchè ci sono le fatture, le fatture immediate eccetera, ma soprattutto le NOTE DI CREDITO (e di debito), più le varianti con firma digitale XAdES eccetera.
    Nell'esempio è una fattura "semplice" (codice 'a')
    
    
       marchiofile:=g_codificanumerofatturaelettronica('a',fatturaanno,fatturanumero);
    
       riceventepec:='';
       riceventecodicedestinatario:='000000';
       if i_dataset.fieldbyname('felpecdestinatario').asstring<>'' then
       begin
           riceventepec:=i_dataset.fieldbyname('felpecdestinatario').asstring;
           riceventecodicedestinatario:='0000000';
       end;
       
      (...) inizializzazioni varie
       
       /// sceglie se usare il campo DITTA oppure cognome+nome
       
       if (i_dataset.fieldbyname('ditta').AsString='')
           AND
           ((i_dataset.fieldbyname('felcognome').AsString='') or (i_dataset.FieldByName('felnome').Asstring='')) then
       begin
           loggaNow('errore 12684: ditta / cognome+nome vuoto');
               Exit;
       end;
    
       if i_dataset.fieldbyname('ditta').AsString<>'' then
       begin
           riceventedenominazione:=i_dataset.fieldbyname('ditta').AsString;
       end
       else
       begin
           riceventenome:=i_dataset.fieldbyname('felnome').asstring;
           riceventecognome:=i_dataset.fieldbyname('felcognome').asstring;
           riceventedenominazione:='';
       end;
    
       if i_dataset.fieldbyname('codicefiscale').AsString='' then
       begin
           loggaNow('Errore 1735: per le fatture elettroniche il codicefiscale ci vuole sempre');
           Exit;
       end;
    
       
     (...) check vari
     
     (...)check su modalità MP05 (bonifico) senza beneficiario, check su IBAN eccetera
     
     /// prende le righe del documento, cioè fa il join esplicito tra testata e righe. normalmente prenderebbe anche i totali (per i casi con IVA diversa nello stesso documento eccetera. è sempre un esempio)
     
       zrighe:=TZQuery.create(nil);
       zrighe.connection:=datdati.zconn;
       ZXSQL(zrighe,'select * from ridocumenti where idlinkrighe="'+i_dataset.fieldbyname('idlink').asstring+'"');
    

    /// qui inizia a generare la fattura vera e propria dentro la variabile "fattura"
    Nulla ti vieterebbe di scrivere, brutalmente, dentro un file di testo, una riga alla volta.
    Per Delphi la cosa "bella" è che, alla fine, con una singola istruzione si scrive in un colpo solo tutto quanto.

    Nota: gli offset che vedi (0,4,8...) sono le spaziature-tab identiche a quelle dell'esempio della fattura Agenzia.
    Configurando opportunamente i parametri salta fuori un file uguale binariamente all'esempio
    
       fattura:=tstringlist.create;
       g_fatturaScriviHeader(fattura);
    
          g_fatturaScriviRiga(0,fattura,'<FatturaElettronicaHeader>');
    
           g_fatturaScriviRiga(4,fattura,'<DatiTrasmissione>');
               g_fatturaScriviRiga(8,fattura,'<IdTrasmittente>');
                   g_fatturaScriviTag(12,fattura,'IdPaese','IT');
                   g_fatturaScriviTag(12,fattura,'IdCodice',i_trasmittentecf);
               g_fatturaScriviRiga(8,fattura,'</IdTrasmittente>');
    
               g_fatturaScriviTag(8,fattura,'ProgressivoInvio',marchiofile);
               g_fatturaScriviTag(8,fattura,'FormatoTrasmissione','FPR12'); /// attenzione sempre hardcoded PRivati 
               g_fatturaScriviTag(8,fattura,'CodiceDestinatario',riceventecodicedestinatario);
    
               g_fatturaScriviRiga(8,fattura,'<ContattiTrasmittente>');
                   g_fatturaScriviTag(12,fattura,'Telefono',i_trasmittentetelefono);
                   g_fatturaScriviTag(12,fattura,'Email',i_trasmittenteemail);
               g_fatturaScriviRiga(8,fattura,'</ContattiTrasmittente>');
    
               g_fatturaScriviTag(8,fattura,'PECDestinatario',riceventepec);
           g_fatturaScriviRiga(4,fattura,'</DatiTrasmissione>');
    
    
    Compila essenzialmente le righe di testo talvolta usando i parametri in ingresso della funzione, altre dai dati presi dal database (cioè dal documento).
    La discrasia è riferita al fatto di poter inviare in modo disgiunto (il commercialista invia i documenti del cliente)
    
    
    
           g_fatturaScriviRiga(4,fattura,'<CedentePrestatore>');
                   g_fatturaScriviRiga(8,fattura,'<DatiAnagrafici>');
    
                       g_fatturaScriviRiga(12,fattura,'<IdFiscaleIVA>');
                           g_fatturaScriviTag(16,fattura,'IdPaese','IT');
                           g_fatturaScriviTag(16,fattura,'IdCodice',i_trasmittentepiva);
                       g_fatturaScriviRiga(12,fattura,'</IdFiscaleIVA>');
    
                       g_fatturaScriviTag(12,fattura,'CodiceFiscale',i_trasmittentecf);
    
                       g_fatturaScriviRiga(12,fattura,'<Anagrafica>');
                       if i_trasmittentedenominazione<>'' then
                           g_fatturaScriviTag(16,fattura,'Denominazione',i_trasmittentedenominazione)
                       else
                       begin
                           g_fatturaScriviTag(16,fattura,'Nome',i_trasmittentenome);
                           g_fatturaScriviTag(16,fattura,'Cognome',i_trasmittentecognome);
                       end;
                       g_fatturaScriviRiga(12,fattura,'</Anagrafica>');
    
                       g_fatturaScriviTag(12,fattura,'RegimeFiscale',i_trasmittenteregimefiscale);
                   g_fatturaScriviRiga(8,fattura,'</DatiAnagrafici>');
    
                   g_fatturaScriviRiga(8,fattura,'<Sede>');
                       g_fatturaScriviTag(12,fattura,'Indirizzo',i_trasmittenteindirizzo);
                       g_fatturaScriviTag(12,fattura,'CAP',i_trasmittentecap);
                       g_fatturaScriviTag(12,fattura,'Comune',i_trasmittentecomune);
                       g_fatturaScriviTag(12,fattura,'Provincia',i_trasmittenteprovincia);
                       g_fatturaScriviTag(12,fattura,'Nazione','IT');
                   g_fatturaScriviRiga(8,fattura,'</Sede>');
    
               g_fatturaScriviRiga(4,fattura,'</CedentePrestatore>');
    
    
    
    
               g_fatturaScriviRiga(4,fattura,'<CessionarioCommittente>');
                   g_fatturaScriviRiga(8,fattura,'<DatiAnagrafici>');
                       if riceventepiva<>'' then
                       begin
                           g_fatturaScriviRiga(12,fattura,'<IdFiscaleIVA>');
                               g_fatturaScriviTag(16,fattura,'IdPaese','IT');
                               g_fatturaScriviTag(16,fattura,'IdCodice',riceventepiva);
                           g_fatturaScriviRiga(12,fattura,'</IdFiscaleIVA>');
                       end;
    
                       g_fatturaScriviTag(12,fattura,'CodiceFiscale',riceventecf);
    
    C'è la solita manfrina tra ditta/denominazione e nome+cognome (eventualmente titolo)
    
                       g_fatturaScriviRiga(12,fattura,'<Anagrafica>');
                           if riceventedenominazione<>'' then
                           g_fatturaScriviTag(16,fattura,'Denominazione',riceventedenominazione)
                           else
                           begin
                               g_fatturaScriviTag(16,fattura,'Nome',riceventenome);
                               g_fatturaScriviTag(16,fattura,'Cognome',riceventecognome);
    
                           end;
                       g_fatturaScriviRiga(12,fattura,'</Anagrafica>');
                  g_fatturaScriviRiga(8,fattura,'</DatiAnagrafici>');
    
    
                   g_fatturaScriviRiga(8,fattura,'<Sede>');
                       g_fatturaScriviTag(12,fattura,'Indirizzo',riceventeindirizzo);
                       g_fatturaScriviTag(12,fattura,'CAP',riceventecap);
                       g_fatturaScriviTag(12,fattura,'Comune',riceventecomune);
                       g_fatturaScriviTag(12,fattura,'Provincia',riceventeprovincia);
                       g_fatturaScriviTag(12,fattura,'Nazione','IT');
                   g_fatturaScriviRiga(8,fattura,'</Sede>');
    
    
               g_fatturaScriviRiga(4,fattura,'</CessionarioCommittente>');
    
       g_fatturaScriviRiga(0,fattura,'</FatturaElettronicaHeader>');
    
    Qui, grosso modo, la prima parte della fattura è preparata.
    Ora va predisposta la porzione dove ci sono gli importi
    
    
    g_fatturaScriviRiga(0,fattura,'<FatturaElettronicaBody>');
    
           g_fatturaScriviRiga(4,fattura,'<DatiGenerali>');
               g_fatturaScriviRiga(8,fattura,'<DatiGeneraliDocumento>');
                   g_fatturaScriviTag(12,fattura,'TipoDocumento',i_fatturatipodocumento);
                   g_fatturaScriviTag(12,fattura,'Divisa','EUR');
                   g_fatturaScriviTag(12,fattura,'Data',datetodatamysql(fatturadata));
                   g_fatturaScriviTag(12,fattura,'Numero',inttostr(fatturanumero));
    
    Certi blocchi sono opzionali, ad esempio se c'è ritenuta oppure no eccetera
    
           if prendiCampoBool(i_dataset,'flagritenuta') then
           begin
                   g_fatturaScriviRiga(12,fattura,'<DatiRitenuta>');
                       g_fatturaScriviTag(16,fattura,'TipoRitenuta','RT01');
                       g_fatturaScriviTag(16,fattura,'ImportoRitenuta',g_moneyafel(i_dataset.fieldbyname('ritenuta').asfloat));
                       g_fatturaScriviTag(16,fattura,'AliquotaRitenuta',g_moneyafel(i_dataset.fieldbyname('perritenuta').asinteger));
                       g_fatturaScriviTag(16,fattura,'CausalePagamento','A');
                   g_fatturaScriviRiga(12,fattura,'</DatiRitenuta>');
           end;
           if prendiCampoBool(i_dataset,'flagritenuta') then
           begin
                   g_fatturaScriviRiga(12,fattura,'<DatiCassaPrevidenziale>');
                       g_fatturaScriviTag(16,fattura,'TipoCassa','TC01');
                       g_fatturaScriviTag(16,fattura,'AlCassa',g_moneyafel(i_dataset.fieldbyname('percassa').asinteger));
                       g_fatturaScriviTag(16,fattura,'ImportoContributoCassa',g_moneyafel(i_dataset.fieldbyname('cp').asfloat));
                       g_fatturaScriviTag(16,fattura,'ImponibileCassa',g_moneyafel(i_dataset.fieldbyname('cassa').asfloat));
                       g_fatturaScriviTag(16,fattura,'AliquotaIVA',g_moneyafel(i_dataset.fieldbyname('periva').asinteger));
                   g_fatturaScriviRiga(12,fattura,'</DatiCassaPrevidenziale>');
           end;
                   g_fatturaScriviTag(12,fattura,'ImportoTotaleDocumento',g_moneyafel(i_dataset.fieldbyname('totaledocumento').asfloat));
           if i_dataset.fieldbyname('testo').asstring<>'' then
                   g_fatturaScriviTag(12,fattura,'Causale',g_testoafel(i_dataset.fieldbyname('testo').asstring));
               g_fatturaScriviRiga(8,fattura,'</DatiGeneraliDocumento>');
           g_fatturaScriviRiga(4,fattura,'</DatiGenerali>');
    
    Chiaramente questa parte (i $$$) dipende fortemente dal tipo di documento, qui ho preso una versione semplificate.
    Ce ne sono caterve (di possibilità)
    In questo caso semplicemente cicla per ogni riga (del documento sul db)
    
           g_fatturaScriviRiga(4,fattura,'<DatiBeniServizi>');
    
           if isDataSetOK(zrighe) then
           begin
               with zrighe do
               begin
                   First;
                   while not Eof do
                   begin
                       g_fatturaScriviRiga(8,fattura,'<DettaglioLinee>');
                           g_fatturaScriviTag(12,fattura,'NumeroLinea',inttostr(numerolinea));
                           g_fatturaScriviTag(12,fattura,'Descrizione',g_testoafel(zrighe.fieldbyname('descrizione').asstring));
    
                           g_fatturaScriviTag(12,fattura,'Quantita',g_moneyafel(zrighe.fieldbyname('quantita').asfloat));
    
                           if zrighe.fieldbyname('umm').asstring<>'' then
                               g_fatturaScriviTag(12,fattura,'UnitaMisura',g_testoafel(zrighe.fieldbyname('umm').asstring));
    
                           if not zrighe.fieldbyname('data').isnull then
                           begin
                               g_fatturaScriviTag(12,fattura,'DataInizioPeriodo',datetodatamysql(zrighe.fieldbyname('data').asdatetime));
                               g_fatturaScriviTag(12,fattura,'DataFinePeriodo',datetodatamysql(zrighe.fieldbyname('data').Asdatetime));
                           end;
    
                           g_fatturaScriviTag(12,fattura,'PrezzoUnitario',g_moneyafel(zrighe.fieldbyname('imponibile').asfloat));
                           g_fatturaScriviTag(12,fattura,'PrezzoTotale',g_moneyafel(zrighe.fieldbyname('totaleimponibile').asfloat));
                           g_fatturaScriviTag(12,fattura,'AliquotaIVA',g_moneyafel(zrighe.fieldbyname('perivadiversa').asinteger));
                       g_fatturaScriviRiga(8,fattura,'</DettaglioLinee>');
                       inc(numerolinea);
                       Next;
                   end;
    
               end;
           end
           else //nessuna linea = 1 linea
           begin
               g_fatturaScriviRiga(8,fattura,'<DettaglioLinee>');
                   g_fatturaScriviTag(12,fattura,'NumeroLinea','1');
                   g_fatturaScriviTag(12,fattura,'Descrizione',g_testoafel(i_dataset.fieldbyname('testo').asstring));
                   g_fatturaScriviTag(12,fattura,'Quantita','1.00');
                           g_fatturaScriviTag(12,fattura,'PrezzoUnitario',g_moneyafel(i_dataset.fieldbyname('totaleimponibile').asfloat));
                           g_fatturaScriviTag(12,fattura,'PrezzoTotale',g_moneyafel(i_dataset.fieldbyname('totaleimponibile').asfloat));
                           g_fatturaScriviTag(12,fattura,'AliquotaIVA',g_moneyafel(i_dataset.fieldbyname('periva').asinteger));
                   g_fatturaScriviRiga(8,fattura,'</DettaglioLinee>');
    
           end;
    
    
    Sopra c'è una particolarità: deve sempre esistere ALMENO una riga di dettaglio.
    Quando non c'è (e nel mio gestionale potrebbe non esserci) crea una singola riga di dettaglio di quantità "1" e importo pari al totale.

    Si continua a seconda dei casi: c'è l'IVA?
    
            if prendiCampoBool(i_dataset,'flagiva') then
            begin
               g_fatturaScriviRiga(8,fattura,'<DatiRiepilogo>');
    
                   g_fatturaScriviTag(12,fattura,'AliquotaIVA',g_moneyafel(i_dataset.fieldbyname('periva').asinteger));
                   g_fatturaScriviTag(12,fattura,'ImponibileImporto',g_moneyafel(i_dataset.fieldbyname('totaleimponibile').asfloat));
                   g_fatturaScriviTag(12,fattura,'Imposta',g_moneyafel(i_dataset.fieldbyname('iva').asfloat));
                   g_fatturaScriviTag(12,fattura,'EsigibilitaIVA','I');
               g_fatturaScriviRiga(8,fattura,'</DatiRiepilogo>');
            end;
           g_fatturaScriviRiga(4,fattura,'</DatiBeniServizi>');
           (...)
    
    E tante altre belle cose che puoi vedere nel file XLS (della documentazione)

    Verso la fine la BASILARE modalità di pagamento
    
       g_fatturaScriviRiga(4,fattura,'<DatiPagamento>');
           g_fatturaScrivitag(8,fattura,'CondizioniPagamento','TP02');
    
           if not i_dataset.fieldbyname('felmodalitapagamento').isnull then
               begin
    
                   g_fatturaScriviRiga(8,fattura,'<DettaglioPagamento>');
                       g_fatturaScriviTag(12,fattura,'Beneficiario',g_testoafel(i_dataset.fieldbyname('felbeneficiario').asstring));
                       g_fatturaScriviTag(12,fattura,'ModalitaPagamento',g_testoafel(i_dataset.fieldbyname('felmodalitapagamento').asstring));
                       g_fatturaScriviTag(12,fattura,'ImportoPagamento',g_moneyafel(i_dataset.fieldbyname('totaledacorrispondere').asfloat));
                       if i_dataset.fieldbyname('felmodalitapagamento').asstring='MP05' then
                       begin
                           g_fatturaScriviTag(12,fattura,'IstitutoFinanziario',g_testoafel(i_dataset.fieldbyname('felistitutofinanziario').asstring));
                           g_fatturaScriviTag(12,fattura,'IBAN',g_testoafel(i_dataset.fieldbyname('feliban').asstring));
                       end;
                   g_fatturaScriviRiga(8,fattura,'</DettaglioPagamento>');
    
           end;
       g_fatturaScriviRiga(4,fattura,'</DatiPagamento>');
    
    g_fatturaScriviRiga(0,fattura,'</FatturaElettronicaBody>');
    
    g_fatturaScriviRiga(0,fattura,'</p:FatturaElettronica>');
    
    Bon, è fatta, va solo scritto il "pacco"
    
       nomefile:=i_cartella+'IT'+uppercase(i_trasmittentecf)+'_'+marchiofile+'.xml';
       SpacchettaDLL(i_cartella+'fatturaordinaria_v1.2.1.xsl','fel');
       fattura.SaveToFile(nomefile);
    
    nel mio caso si crea il nome del file marchiato (cioè con la codifica base62 di anno e numero).
    Si "appiccica" anche l'XSL (per generare la versione PDF)
    
       nomepdf:=i_cartella+'IT'+uppercase(i_trasmittentecf)+'_'+marchiofile+'_'+format('%.04d_%.04d',[i_dataset.fieldbyname('anno').asinteger,i_dataset.fieldbyname('progressivo').asinteger])+'.pdf';
    
       g_xmltopdf(nomefile,i_cartella+'fatturaordinaria_v1.2.1.xsl',nomepdf);
    
    E' una mia funzione che da XML (e XSL) crea il PDF
    Il quale può essere "appiccicato" mime64 nello XML o spedito a parte eccetera
    
       if FileExists(nomefile) then
           result:=nomefile;
       fattura.Free;
    end;
    
  • Re: Fattura Elettronica in VB6 o export xml

    Funzioni aggiuntive
    
    /// crea spaziatura come negli esempio agenzia entrate
    function g_spazi(i_volte:integer):string;
    var
       i:integer;
    begin
       result:='';
       if i_volte<=0 then Exit;
       for i:=1 to i_volte div 4 do
           Result:=result+chr(9);
    end;
    
    /// scrive lo header standard. Attenzione, c'è hardcoded FPR (cioè quella PRIVATI)
    
    function g_fatturaScriviHeader(i_fattura:tstringlist):Boolean;
    begin
       result:=False;
       if i_fattura=nil then Exit;
       i_fattura.add('<?xml version="1.0" encoding="UTF-8"?>');
       i_fattura.add('<?xml-stylesheet type="text/xsl" href="fatturaordinaria_v1.2.1.xsl"?>');
       i_fattura.add('<p:FatturaElettronica versione="FPR12" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"');
       i_fattura.add('xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2"');
       i_fattura.add('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"');
       i_fattura.add('xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd">');
       result:=True;
    end;
    
    //scrive una riga con spaziatura a sinistra
    
    function g_fatturaScriviRiga(i_offset:Integer;i_fattura:tstringlist;i_riga:string):Boolean;
    var
       i:Integer;
       s:string;
    begin
       result:=False;
       if i_offset<0 then
       begin
         loggaNow('Errore 12212 i_offset negativo');
         exit;
       end;
       if i_fattura=nil then
       begin
           loggaNow('Errore 445 i_fattura vuota');
           Exit;
       end;
       if i_riga='' then
       begin
           logganow('Errore 3359 i_riga vuota');
           Exit;
       end;
       i_fattura.add(g_spazi(i_offset)+i_riga);
       result:=True;
    end;
    
    /// mette un tag XML <qualcosa>
    
    function g_fatturaScriviTag(i_offset:Integer;i_fattura:tstringlist;i_tag:string;i_stringa:string):Boolean;
    begin
       result:=False;
       if i_offset<0 then
       begin
         loggaNow('Errore 44212 i_offset negativo');
         exit;
       end;
       if i_fattura=nil then
       begin
           logganow('Errore 3422 fattura vuota');
           exit;
       end;
        if i_tag='' then
       begin
           logganow('Errore 6859 i_tag vuoto');
           Exit;
       end;
       i_fattura.add(g_spazi(i_offset)+'<'+i_tag+'>'+i_stringa+'</'+i_tag+'>');
      result:=True;
    end;
    
  • Re: Fattura Elettronica in VB6 o export xml

    Come vedi, al di là delle differenze con VB, la logica è piuttosto semplice.
    I "drammi drammatici" ci sono per le situazioni più complesse (abbuoni, ritenute sì, ritenute no, sconti sì, arrotondamenti no, DDT e così via).
    Come accennato, quando ho difficoltà, piglio il programma ufficiale e guardo come scrive il file XML, e poi... copio.
  • Re: Fattura Elettronica in VB6 o export xml

    Intanto un grazie sentito per tutto il materiale postato!
    Proverò a capire meglio studiando quello che hai messo a disposizione. Nel frattempo ho trovato in rete diversi spunti e qualche software gratuito che mi può dare un'dea della gestione dei campi da aggiungere e qualcos'altro.

    Saluti
  • Re: Fattura Elettronica in VB6 o export xml

    +m2+ ha scritto:


    Per i casi più strani ho scaricato il programma java ufficiale della agenzia entrate, ho messo i dati che mi servivano, per poi studiare lo xml generato.
    Ciao,

    potresti per cortesia indicare il link dove scaricare il programma ufficiale dell'ADE ? Sto creando anch'io l'XML per le fatture di mio cognato in Delphi.

    Ciao e grazie.
  • Re: Fattura Elettronica in VB6 o export xml

  • Re: Fattura Elettronica in VB6 o export xml

    +m2+ ha scritto:


    Ti ringrazio molto, il link l'avevo già visto ma cliccandoci sopra credevo mi scaricasse un exe invece mi faceva scaricare un jnlp e non sapevo cos'era, adesso ho capito che è una cosa legata a java.

    Ti ringrazio molto.

    Ciao
  • Re: Fattura Elettronica in VB6 o export xml

    Un saluto a tutti.
    Ho seguito questo thread con interesse, visto che anche io ho da poco realizzato una modifica ad un vecchio programma scritto in VB6 per consentirne la gestione della fatturazione elettronica.
    Ho avuto qualche problema con alcuni campi del database (dove vi sono esclusivamente i dati per la generazione dell'XML per la fatturazione elettronica).
    Sapete dove posso trovare la struttura di un database (in qualunque formato: da Access a MySQL o Postgresql) con i corretti campi per la fatturazione elettronica? Giusto per fare un confronto col mio. Grazie.
  • Re: Fattura Elettronica in VB6 o export xml

    Dipende quanto è complessa la struttura delle fatture che fai. Le possibilità sono tantissime, ma quasi mai usate
Devi accedere o registrarti per scrivere nel forum
25 risposte